home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / dev / misc / fd2pragma.lha / fd2pragma / Source / fd2pragma.c next >
Text File  |  2002-10-27  |  380KB  |  11,759 lines

  1. static const char version[] = "$VER: fd2pragma 2.158 (19.10.2002) by Dirk Stoecker <stoecker@epost.de>";
  2. /* #define FD2PRAGMA_READARGS */
  3. /* #define FD2PRAGMA_AMIGA */
  4. /* #define DEBUG */
  5. /* #define DEBUG_OLD */
  6.  
  7. /* Programmheader
  8.  
  9.         Name:           fd2pragma
  10.         Author:         SDI
  11.         Distribution:   PD
  12.         Description:    creates pragmas files, lvo files, ...
  13.         Compileropts:   -
  14.         Linkeropts:     -
  15.  
  16.  1.2    : added pragmas for the Dice compiler. Available via switch "Dice".
  17.         added switches "Aztec", "SAS" and "Maxon": Maxon and Aztec just
  18.         turn on the default (except that Maxon expects pragma files to be
  19.         called "xxx_pragmas.h" instead of "xxx_lib.h"), SAS is equal to
  20.         Dice, except that SAS supports the pragma tagcall.
  21.  2.0    : Added support for tag functions. See the docs for details.
  22.         Author until this version:
  23.         Jochen Wiedmann
  24.         Am Eisteich 9
  25.         72555 Metzingen (Germany)
  26.         Tel. 07123 / 14881
  27.  2.1   19.08.96 : now made by SDI, added correct __MAXON__ support and
  28.         support for StormC++, added auto recognition of tagcall functions
  29.         changed the CLI interface completely
  30.  2.2   21.08.96 : fixed a lot of errors, added debug code
  31.  2.3   22.08.96 : little changes
  32.  2.4   24.08.96 : added proto-file creation
  33.  2.5   25.08.96 : added syscall and fix for functions ending in ...DMA
  34.  2.6   26.08.96 : fixed some errors, added CLIB parameter (used later for
  35.         CSTUBS)
  36.  2.7   01.09.96 : added correct Storm definition, added CLIB scan
  37.  2.8   02.09.96 : added assembler stub functions, added first ASM-stub code
  38.  2.9   04.09.96 : added Comment-Support
  39.  2.10  05.09.96 : changed CSTUB creation a bit
  40.  2.11  07.09.96 : speeded up output, reduced number of strndup calls
  41.  2.12  26.09.96 : pressing CTRL-C in early startup brought a wrong error
  42.         message - fixed
  43.  2.13  30.09.96 : made RegNames field to RegNames string - shorter Exe-file
  44.  2.14  01.10.96 : made SPECIAL 6 default, COMMENT also in LVO files
  45.  2.15  13.10.96 : corrected an error text
  46.  2.16  14.10.96 : added correct comment support and PRIVATE option
  47.  2.17  19.10.96 : now Maxon-compiled in Small data mode
  48.  2.18  22.10.96 : removed EXTERNC in Storm, Maxon and all pragmas, corrected
  49.         the texts, again SAS compiled
  50.  2.19  26.10.96 : added option to create FD files out of pragma files,
  51.         reworked a lot in the source
  52.  2.20  27.10.96 : fixed errors of previous version
  53.  2.21  28.10.96 : fixed error in CLIB scan
  54.  2.22  27.11.96 : SPECIAL numbers for lib and ASM code were wrong, removed
  55.         bug in Tag function stubs
  56.  2.23  06.12.96 : lib and stub creation still was wrong
  57.  2.24  31.12.96 : formed stub libs matching C++ file names, corrected CLIB
  58.         scan errors
  59.  2.25  04.01.97 : added HEADER option (I was asked for)
  60.  2.26  05.01.97 : added HEADER scan (in old file) and auto inserting
  61.  2.27  10.01.97 : stub functions missed register saving, outfuncs skip now,
  62.         when error occured (makes lots of error checking obsolete)
  63.  2.28  11.01.97 : forgot to add offset made by register saving
  64.  2.29  18.01.97 : now libtags and amitags defines only, when at least 1
  65.         tagfunc
  66.  2.30  13.02.97 : added local library base functions, rearranged SPECIAL
  67.         options, fixed some bugs
  68.  2.31  15.02.97 : corrected bugs inserted in previous version
  69.  2.32  16.02.97 : and again bug fixes, still didn't work
  70.  2.33  18.02.97 : corrected texts, added SPECIAL 28
  71.  2.34  25.03.97 : corrected Pragma --> FD file conversion, added ##shadow
  72.  2.35  26.03.97 : added STORMFD option, COMMENT, PRIVATE work again
  73.  2.36  29.03.97 : corrected *tagcall scan a bit
  74.  2.37  20.06.97 : added PASCAL stub lib production (SPECIAL 14, 15)
  75.  2.38  01.07.97 : fixed ##end handling
  76.  2.39  20.07.97 : added better proto file (__GNUC__ inline and pragma call),
  77.         removed C++ comments
  78.  2.40  24.11.97 : added new basenames to the list (devices and resources),
  79.         added tag-exception name checking (dos, utility libraries)
  80.  2.41  27.11.97 : fixed little bug with private functions, CSTUBS now
  81.         special option and no longer commandline arg, SPECIAL 10-15 got
  82.         numbers 11-16 (Sorry)
  83.  2.42  28.11.97 : Added two new warnings for CLIB
  84.  2.43  12.12.97 : faster FD file scan, one new warning
  85.  2.44  19.12.97 : fixed MODE settings for SPECIAL 15,16
  86.  2.45  30.01.98 : added function recognition, included inline creation,
  87.         inline stuff is based on fd2inline 1.11 (incomplete)
  88.  2.46  31.01.98 : continued inline stuff, fixed clib functions
  89.  2.47  05.02.98 : completed inline stuff, added alias names for dos functions
  90.  2.48  06.02.98 : changed Func interface - flags instead of tagmode
  91.  2.49  10.02.98 : fixed inline generation a bit, added SORTED argument,
  92.         RegNames got strings again
  93.  2.50  11.02.98 : bug-fixes, still did not work completely, hopefully got
  94.         all now
  95.  2.51  12.02.98 : and bug-fixes again :-(
  96.  2.52  15.02.98 : changed sorting order of arguments
  97.  2.53  20.02.98 : some code style changes
  98.  2.54  25.02.98 : added SMALLDATA model, removed 5 global variables (better
  99.         style), stub libs use MOVEM when possible, own MemRemember function
  100.  2.55  26.02.98 : bug fixes
  101.  2.56  15.03.98 : added FPU support
  102.  2.57  17.03.98 : added NOFPU keyword
  103.  2.58  19.03.98 : little fixes
  104.  2.59  20.03.98 : added enum and external type definitions defines
  105.  2.60  22.03.98 : added external types file scan
  106.  2.61  23.03.98 : fixed SAS flibcall, added FPU stubs
  107.  2.62  28.03.98 : bug fix with NOFPU and new option FPUONLY, total new clib
  108.         handling
  109.  2.63  29.03.98 : really lots of bug fixes, There are so much problems.
  110.         A better definition format would have been wonderful.
  111.  2.64  05.04.98 : bug fixes
  112.  2.65  07.04.98 : fixed Enforcer hit
  113.  2.66  08.04.98 : bug fix with type detection
  114.  2.67  20.04.98 : added GNU-only stuff
  115.  2.68  28.04.98 : SPECIAL 8 defaults to SAS-C names now
  116.  2.69  25.05.98 : added PowerUP stuff support
  117.  2.70  28.05.98 : added SAS PowerUP stuff, fixed error with function
  118.         detection in CLIB scan
  119.  2.71  30.05.98 : added PowerUP Inlines
  120.  2.72  12.06.98 : sorting turns of COMMENT now
  121.  2.73  05.07.98 : added first FPC stuff, added HEADER to PowerUP stuff,
  122.         added PASCAL header scan
  123.  2.74  06.07.98 : finished FPC stuff
  124.  2.75  07.07.98 : bug fixes for FPC stuff
  125.  2.76  09.07.98 : style changes for FPC stuff, bug fixes
  126.  2.77  11.07.98 : hopefully last FPC bug removed
  127.  2.78  23.07.98 : style changes and bug fixes for FPC stuff, more comments
  128.  2.79  10.08.98 : bug fix, when TO was used with a directory, clib got
  129.         wrong path if it was a relative path description
  130.  2.80  16.08.98 : now prints better error when filopen failed
  131.  2.81  26.10.98 : added BMAP files for BASIC, CODE needs to use large mode
  132.         now :-(
  133.  2.82  28.10.98 : optimizations and bug fixes
  134.  2.83  31.12.98 : fixed powerup stuff a bit
  135.  2.84  05.01.99 : fixed bug in Lib creation, when Dx/Ax and FPx were mixed
  136.  2.85  06.01.99 : added recognition of names ending in MESA, added notagcall
  137.         comment support, void functions no longer can be tagcall
  138.  2.86  10.01.99 : added BGUI special funcs, fixed bug in SPECIAL 42 code
  139.  2.87  12.01.99 : added asm-text (SECTION), moved 12-17 to 13-18
  140.  2.88  17.01.99 : better type detection, added some more basenames, some
  141.         little bug fixes, new makefile reduces file size a lot
  142.  2.89  17.07.99 : added union support
  143.  2.90  12.11.99 : added new motorola syntax, opt040 and vbcc inlines
  144.  2.91  13.11.99 : Now supports changes in OS3.5 includes, why the hell must
  145.         such changes be? I thought new includes will bring cleanup and not
  146.         cleandown. And the reported bugs are still unfixed, but there are
  147.         new ones!, bug-fixes
  148.  2.92  14.11.99 : added PPC-WOS library text and code, FD-creation moved from
  149.         80 to 200 (now finally! - there should be enough free number space),
  150.         added VBCC-PUP text generation
  151.  2.93  15.11.99 : added CheckError function, moved DisplayInfoHandle to
  152.         types definition file
  153.  2.94  16.11.99 : added first VBCC-PowerUP-Lib production stuff, only ELF
  154.         tables missing
  155.  2.95  17.11.99 : finished PowerUP stub stuff, startet PPC-ABI stuff
  156.  2.96  18.11.99 : little bug fixes
  157.  2.97  19.11.99 : added SECTION keyword, moved 11-18 to 12-17, ahh 3 releases
  158.         more and we get an anniversary, my first program using third revision
  159.         digit :-)
  160.  2.98  20.11.99 : added VBCC-WOS-Code for PPC libs
  161.  2.99  25.11.99 : bug fixes
  162.  2.100 17.02.00 : fixed bug for VBCC inlines
  163.  2.101 29.02.00 : fixed name for VBCC inlines
  164.  2.102 13.03.00 : added new style GCC inlines
  165.  2.103 21.03.00 : bug fixed, SPECIAL 35 has VBCC stuff now.
  166.  2.104 25.03.00 : fixed path lock problem
  167.  2.105 11.04.00 : library HUNK_UNIT get functionname now
  168.  2.106 13.07.00 : added E-Modules
  169.  2.107 06.08.00 : removed VBCC inline support from 35 and moved it to 38, 35
  170.         does now skip pragma/inline files for VBCC
  171.  2.108 18.08.00 : added new ppc modification proto file 39, modified protos a
  172.         bit, support for register types and function pointer args, int got
  173.         internally type CPP_TYPE_INT
  174.  2.109 19.08.00 : bug fixes
  175.  2.110 24.08.00 : fixed SPECIAL 7,40-44, added SPECIAL 80-83
  176.  2.111 31.08.00 : bug fixes
  177.  2.112 03.09.00 : FD2Pragma.types scanner no longer accepts multi-word types.
  178.  2.113 29.12.00 : added extern keword support for return types.
  179.  2.114 07.01.01 : made FD2Pragma partly portable, removed 4 direct pragma arguments
  180.  2.115 14.01.01 : lots of bug fixes, renamed from FD2Pragma to fd2pragma
  181.  2.116 28.01.01 : added internal types, SPECIAL 90, NOCPPNAMES and bug fixes,
  182.         VBCC inlines fix for data in A-regs
  183.  2.117 04.02.01 : changed NOCPPNAMES to ONLYCNAMES, added HUNKNAME, LocCode is
  184.         portable, added BASENAME, added VBCCWOSInlines
  185.  2.118 07.02.01 : added destination file printout, LIBTYPE, fixes VBCC-PUP-Code
  186.  2.119 11.02.01 : bug fixes
  187.  2.120 17.02.01 : added NOPPCREGNAME, bug fixes
  188.  2.121 04.03.01 : added MorphOS text
  189.  2.122 11.03.01 : little bug fixes
  190.  2.123 03.04.01 : now uses EXT_DEXT16 instead of EXT_REF16 also for 68k files
  191.  2.124 08.04.01 : bug fixes, added MorphOS binary mode, finally full portable
  192.  2.125 28.04.01 : added LVO's for PPC, started support for SFD format
  193.  2.126 29.05.01 : fixed PPC LVO's, removed STORMFD Option (auto detection),
  194.         now handles up to 5 alias names, finished SFD format read, added FD
  195.         creation, added keyword checks for argument names, lots of optimizations
  196.         and fixes, which came in hand with SFD inclusion.
  197.         Thanks Olaf Barthel for making the SFD stuff possible.
  198.  2.127 30.04.01 : private comments are skipped now, finished SFD production,
  199.         fixed bugs, removed SPECIAL 8 redirect (is replaced by 80-83)
  200.  2.128 01.05.01 : bug fixes
  201.  2.129 03.06.01 : included support for files previous made by vbcc genauto tool
  202.  2.130 04.06.01 : bug fixes in genauto stuff
  203.  2.131 11.06.01 : newer types handle cia now correct
  204.  2.132 27.06.01 : fixed crash caused by illegal interpretation of ANSI-C :-)
  205.  2.133 28.06.01 : added VOIDBASE argument
  206.  2.134 01.07.01 : added MorphOS types, fixed PowerUp stuff
  207.  2.135 28.07.01 : added VBCC inline varargs support
  208.  2.136 30.07.01 : fixed VBCC inline varargs
  209.  2.137 18.11.01 : little bug-fix
  210.  2.138 30.11.01 : fixed CLIB scanning (now a preparser cleans the file a lot)
  211.  2.139 13.12.01 : fixed ==libname scan and xvsBase
  212.  2.140 21.12.01 : fixed some uint32 in created files, which have been wrongly
  213.         introduced in 2.1xx versions when making tool portable
  214.  2.141 04.01.02 : fixed problem with multiple pointer function args like in
  215.         "void (**func)(void)"
  216.  2.142 07.01.02 : started new direct inline types 46 and 47.
  217.  2.143 08.01.02 : Fixed warnings, bugs, card.resouce entry and added
  218.         ==copyright directive
  219.  2.144 09.01.02 : Fixed MUI varargs inlines
  220.  2.145 03.03.02 : Some bug fixes
  221.  2.146 20.05.02 : one little bug fix, added support for missing empty () in
  222.         defective FD files
  223.  2.147 01.05.02 : now continues when detecting no fd-arg name
  224.  2.148 09.06.02 : fixed problem with MorphOS stubs, added AUTOHEADER keyword,
  225.         added auto type defaults to int, fixed bug with STACK type
  226.  2.149 24.06.02 : fixed lots of problems found when converting amissl includes
  227.  2.150 08.08.02 : fixed inline files a bit
  228.  2.151 31.08.02 : fixed SPECIAL 46 files (error when no args, but return value)
  229.  2.152 01.09.02 : bug-fix with SPECIAL 47
  230.  2.153 11.09.02 : modified SPECIAl 46 varargs on request of Sebastian Bauer
  231.         and Olaf Barthel
  232.  2.154 03.10.02 : added VBCC MorphOS inlines (SPECIAL 122). Thanks Frank Wille
  233.         for design help.
  234.  2.155 04.10.02 : optimized VBCC MorphOS text (SPECIAL 93), fixed VBCC MorphOS
  235.         inlines
  236.  2.156 06.10.02 : added warning about obsolete types, fixed VBCC MorphOS Code
  237.         (SPECIAL 78)
  238.  2.157 12.10.02 : Fixed CLIB scan problem
  239.  2.158 19.10.02 : added CLIB define in SPECIAL 46
  240. */
  241.  
  242. /* A short note, how fd2pragma works.
  243. Working mode for SPECIAL 200 is a bit different!
  244. The main function parses arguments. Switches are converted into FLAG_XXX values
  245. and stored in global "Flags" or "Flags2" variable. SPECIAL numbers are parsed and are used
  246. to call a CreateXXX function, with its interface depending on the need of
  247. arguments (Some have 2, some none, ...). Before SPECIAL arguments are parsed,
  248. fd2pragma loads (S)FD file and scans it using ScanFDFile(). If SORTED is specified,
  249. the list gets sorted nearly directly afterwards. IF CLIB argument is given, the clib
  250. file is scanned after FD file and a clib list is created. Now SPECIAL is parsed
  251. and mode is set to any of the MODUS_XXX values. Also the destination file name
  252. is created if not given. The destination file is opened now. The mode variable
  253. is used to determine the correct CreateXXX function, which is called afterwards.
  254. This function produces file headers and stuff like that and calls CallFunc to
  255. process each FD entry. CallFunc gets 3 arguments. First the workmode (TAG,
  256. NORMAL, BOTH). Second the comment method (for C it is "/%s *\x2F\n",
  257. for ASM it is "\n%s", no comment is reached with 0 argument). The last is most
  258. important. It is the function pointer to a function creating the entries.
  259. These functions have always the same interface and are called through CallFunc
  260. only! They create an entry for the specified function (e.g. FD entry).
  261. Parsing special functions, adding comments, checking for tag-functions, ...
  262. is done by CallFunc. It is no problem to call CallFunc multiple with different
  263. function pointers (as is done for SPECIAL 6 pragmas).
  264.  
  265. The functions can use DoOutput to output texts in printf style or DoOutputDirect
  266. to output all data in fwrite style. Buffering is done automatically.
  267.  
  268. fd2pragma has its own memory managment. All memory must be allocated using
  269. AllocListMem and is freed automatically. This is especially useful for DupString
  270. function, which is used in FD and CLIB scanner.
  271.  
  272. Normally this source-file is to big and should be splitted in different files
  273. compiled alone and linked together. :-) It takes about 20 minutes to compile it
  274. on my Amiga system with optimizations turned on.
  275. */
  276.  
  277. #include <ctype.h>
  278. #include <stdio.h>
  279. #include <stdlib.h>
  280. #include <string.h>
  281. #include <stdarg.h>
  282. #include <time.h>
  283.  
  284. /* These are the only allowed variable types of all related programs! */
  285. typedef signed char         int8;       /* signed 8 bit */
  286. typedef unsigned char      uint8;       /* unsigned 8 bit */
  287. typedef signed short int    int16;      /* signed 16 bit */
  288. typedef unsigned short int uint16;      /* unsigned 16 bit */
  289. typedef signed long int     int32;      /* signed 32 bit */
  290. typedef unsigned long int  uint32;      /* unsigned 32 bit */
  291. typedef float                fl32;      /* 32 bit IEEE float value */
  292. typedef double               fl64;      /* 64 bit IEEE double value */
  293. typedef char               string;      /* the string datatype [e.g. one character of string!] */
  294. typedef char *             strptr;      /* and an string pointer */
  295.  
  296. #define EndPutM32(a, b) {uint32 epu32 = (b); (a)[0] = (uint8) (epu32 >> 24); (a)[1] = (uint8) (epu32 >> 16); \
  297.                                              (a)[2] = (uint8) (epu32 >> 8); (a)[3] = (uint8) epu32;}
  298. #define EndPutM16(a, b) {uint16 epu16 = (b); (a)[0] = (uint8) (epu16 >> 8); (a)[1] = (uint8) epu16;}
  299. #define EndPutI32(a, b) {uint32 epu32 = (b); (a)[3] = (uint8) (epu32 >> 24); (a)[2] = (uint8) (epu32 >> 16); \
  300.                                              (a)[1] = (uint8) (epu32 >> 8); (a)[0] = (uint8) epu32;}
  301. #define EndPutI16(a, b) {uint16 epu16 = (b); (a)[1] = (uint8) (epu16 >> 8); (a)[0] = (uint8) epu16;}
  302.  
  303. #define EndPutM32Inc(a, b) {EndPutM32(a,b); (a) += 4;}
  304. #define EndPutM16Inc(a, b) {EndPutM16(a,b); (a) += 2;}
  305. #define EndPutI32Inc(a, b) {EndPutI32(a,b); (a) += 4;}
  306. #define EndPutI16Inc(a, b) {EndPutI16(a,b); (a) += 2;}
  307.  
  308. #define TEXT_SAS        "__SASC"        /* verified     */
  309. #define TEXT_SAS_60     "__SASC_60"     /* verified     */
  310. #define TEXT_MAXON      "__MAXON__"     /* verified     */
  311. #define TEXT_STORM      "__STORM__"     /* verified     */
  312. #define TEXT_DICE       "_DCC"          /* in 2.0 code  */
  313. #define TEXT_AZTEC      "AZTEC_C"       /* verified     */
  314. #define TEXT_GNUC       "__GNUC__"      /* verified     */
  315. #define TEXT_VBCC       "__VBCC__"      /* verified     */
  316.  
  317. #define TEMPSIZE        20480
  318.  
  319. #define FLAG_EXTERNC     (1<< 0) /* add externc statements */
  320. #define FLAG_SYSCALL     (1<< 1) /* create SAS-C syscall pragmas */
  321. #define FLAG_DOCOMMENT   (1<< 2) /* do comment processing */
  322. #define FLAG_PRIVATE     (1<< 3) /* also use private functions */
  323. #define FLAG_LOCALREG    (1<< 4) /* local file uses register call */
  324. #define FLAG_ISPRIVATE   (1<< 5) /* for FD creation, currently working in private mode */
  325. #define FLAG_PASCAL      (1<< 6) /* library creation with PASCAL style */
  326. #define FLAG_SMALLDATA   (1<< 7) /* libraries use small data modell */
  327. #define FLAG_DONE        (1<< 8) /* destination file is not empty */
  328. #define FLAG_INLINENEW   (1<< 9) /* produce new style inlines */
  329. #define FLAG_INLINESTUB  (1<<10) /* produce stubs style inlines */
  330. #define FLAG_NOFPU       (1<<11) /* do not allow FPU registers */
  331. #define FLAG_DIDERROR    (1<<12) /* one error already printed, don't print 2nd */
  332. #define FLAG_FPUONLY     (1<<13) /* only use FPU registers */
  333. #define FLAG_GNUPRAG     (1<<14) /* insert inline call into pragma file */
  334. #define FLAG_POWERUP     (1<<15) /* create Phase5 PowerUP files */
  335. #define FLAG_ASMSECTION  (1<<16) /* create SECTIONS in Asm code */
  336. #define FLAG_NEWSYNTAX   (1<<17) /* new motorola syntax */
  337. #define FLAG_NOMOVEM     (1<<18) /* 68040 optimization, don't use MOVEM */
  338. #define FLAG_WOSLIBBASE  (1<<19) /* first arg is libbase for VBCC WOS */
  339. #define FLAG_NOPPC       (1<<20) /* do not allow PPC functions */
  340. #define FLAG_PPCONLY     (1<<21) /* only take PPC functions */
  341. #define FLAG_NOSYMBOL    (1<<23) /* do not create symbol section for libs */
  342. #define FLAG_MORPHOS     (1<<24) /* create MorphOS files */
  343. #define FLAG_SORTED      (1<<25) /* sort the functions by name */
  344. #define FLAG_DIDPPCWARN  (1<<26) /* we already printed ppc warning */
  345. #define FLAG_SINGLEFILE  (1<<27) /* create single files */
  346. #define FLAG_ONLYCNAMES  (1<<28) /* do not create C++, ASM names */
  347. #define FLAG_BASENAME    (1<<29) /* Basename was command-line specified */
  348. #define FLAG_DIDM68KWARN (1<<30) /* we already printed M68K warning */
  349. #define FLAG_ABIV4       (1<<31) /* ABI V4 design for PPC-LVO */
  350.  
  351. #define FLAG2_SFDMODE       (1<< 0) /* input file was SFD file */
  352. #define FLAG2_LIBTYPE       (1<< 1) /* libtype was specified on command line */
  353. #define FLAG2_CLIBOUT       (1<< 2) /* output type is CLIB */
  354. #define FLAG2_SYSTEMRELEASE (1<< 3) /* systemrelease special comment handling */
  355. #define FLAG2_SFDOUT        (1<< 4) /* output type is SFD */
  356. #define FLAG2_LIBNAME       (1<< 5) /* libname was specified on command line */
  357. #define FLAG2_SMALLCODE     (1<< 6) /* libraries use small code modell */
  358. #define FLAG2_VOIDBASE      (1<< 7) /* library base should be of type "void *" */
  359. #define FLAG2_INLINEMAC     (1<< 8) /* use inline macro instead of inline function */
  360. #define FLAG2_DIRECTVARARGS (1<< 9) /* direct varargs for MorphOS stub libs */
  361. #define FLAG2_PRELIB        (1<<10) /* MorphOS gate PRELIB flag */
  362. #define FLAG2_POSTLIB       (1<<11) /* MorphOS gate POSTLIB flag */
  363. #define FLAG2_REGLIB        (1<<12) /* MorphOS gate REGLIB flag */
  364. #define FLAG2_OLDVBCC       (1<<13) /* old VBCC style */
  365. #define FLAG2_SMALLTYPES    (1<<14) /* allow small data types */
  366. #define FLAG2_AUTOHEADER    (1<<15) /* creates auto generated header */
  367.  
  368. #define FUNCFLAG_NORMAL     (1<<0) /* normal function */
  369. #define FUNCFLAG_TAG        (1<<1) /* a tagcall function */
  370. #define FUNCFLAG_ALIAS      (1<<2) /* an alias name for previous function */
  371. #define FUNCFLAG_EXTENDMODE (1<<3) /* name and args extension for CSTUBS */
  372.  
  373. /* Different modes the main program uses, one for each different file
  374.    type (except for those done with one function and flag settings). */
  375. #define MODUS_STUBTEXT           1
  376. #define MODUS_STUBCODE           2
  377. #define MODUS_LOCALDATA          3
  378. #define MODUS_PRAGMA             4
  379. #define MODUS_CSTUB              5
  380. #define MODUS_SASPOWER           6
  381. #define MODUS_PROTOPOWER         7
  382. #define MODUS_BMAP               8
  383. #define MODUS_PASCAL             9
  384. #define MODUS_VBCCINLINE        10
  385. #define MODUS_VBCCPUPLIB        11
  386. #define MODUS_LVOLIB            12
  387. #define MODUS_EMODULE           13
  388. #define MODUS_REDIRECT          14
  389. #define MODUS_ASMTEXTSF         15
  390. #define MODUS_VBCCPUPTEXTSF     16
  391. #define MODUS_VBCCWOSTEXTSF     17
  392. #define MODUS_VBCCWOSINLINE     18
  393. #define MODUS_VBCCMORPHTEXTSF   19
  394. #define MODUS_VBCCMORPHCODE     20
  395. #define MODUS_LVOLIBPPC         21
  396. #define MODUS_FD                22
  397. #define MODUS_CLIB              23
  398. #define MODUS_SFD               24
  399. #define MODUS_GATESTUBS         25
  400. #define MODUS_VBCCMORPHINLINE   26
  401. #define MODUS_LVO               50    /* and 51 and 52 and 53   */
  402. #define MODUS_PROTO             60    /* and 61 to 69           */
  403. /* new protos start with 90, but are added to MODUS_PROTO ! */
  404. #define MODUS_INLINE            80    /* and 81 to 86           */
  405. #define MODUS_VBCC              90    /* and 91 to 94           */
  406. #define MODUS_LVOPPC            100   /* and 101                */
  407. #define MODUS_GENAUTO           110   /* and 111 to 113         */
  408. #define MODUS_ERROR             200
  409.  
  410. #define ABI_M68K                1
  411. #define ABI_PPC                 2
  412. #define ABI_PPC2                3
  413. #define ABI_PPC0                4
  414.  
  415. /* call types for CallFunc */
  416. #define TAGMODE_NORMAL  0    /* produce normal functions only */
  417. #define TAGMODE_TAGS    1    /* produce only tag functions */
  418. #define TAGMODE_BOTH    2    /* produce both types */
  419.  
  420. /* types specifying name method for pragma creation */
  421. #define PRAGMODE_PRAGLIB        1
  422. #define PRAGMODE_PRAGSLIB       2
  423. #define PRAGMODE_PRAGSPRAGS     3
  424. #define PRAGMODE_NONE           4
  425.  
  426. #define BIAS_START       30 /* the library start offset */
  427. #define BIAS_OFFSET      6  /* value to switch from one to next function */
  428.  
  429. #ifndef FD2PRAGMA_AMIGA
  430. #define EXTTYPESFILEHIDDEN ".fd2pragma.types"
  431. #endif
  432. #ifndef EXTTYPESFILE
  433. #define EXTTYPESFILE       "fd2pragma.types"
  434. #endif
  435. #ifndef EXTTYPESFILE2
  436. #ifdef FD2PRAGMA_AMIGA
  437. #define EXTTYPESFILE2      "PROGDIR:fd2pragma.types"
  438. #else
  439. #define EXTTYPESFILE2      "/usr/local/share/fd2pragma.types"
  440. #endif
  441. #endif
  442.  
  443. #define AUTOHEADERTEXT "Automatically generated header! Do not edit!"
  444.  
  445. #define FDFILEEXTENSION  "_lib.fd"
  446. #define SFDFILEEXTENSION "_lib.sfd"
  447.  
  448. static const strptr RegNames[] = {
  449. "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
  450. "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
  451. "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7",
  452. };
  453.  
  454. static const strptr RegNamesUpper[] = {
  455. "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
  456. "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
  457. "FP0", "FP1", "FP2", "FP3", "FP4", "FP5", "FP6", "FP7",
  458. };
  459.  
  460. enum Register_ID {
  461. REG_D0, REG_D1, REG_D2, REG_D3, REG_D4, REG_D5, REG_D6, REG_D7,
  462. REG_A0, REG_A1, REG_A2, REG_A3, REG_A4, REG_A5, REG_A6, REG_A7,
  463. REG_FP0, REG_FP1, REG_FP2, REG_FP3, REG_FP4, REG_FP5, REG_FP6, REG_FP7
  464. };
  465. #define MAXREGPPC       26
  466. #define MAXREG          24 /* maximum registers of 68K */
  467. #define MAXREGNF        16 /* maximum register number without float regs */
  468. #define UNDEFREGISTER   255 /* for type scanner */
  469.  
  470. struct Args {
  471.   strptr infile;
  472.   strptr to;
  473.   strptr clib;
  474.   strptr header;
  475.   int32  special;
  476.   int32  mode;
  477. };
  478.  
  479. struct ShortList {
  480.   struct ShortList    *Next;
  481. };
  482.  
  483. struct ShortListRoot {
  484.   struct ShortList    *First;
  485.   struct ShortList    *Last;
  486.   size_t               Size;
  487. };
  488.  
  489. #define AMIPRAGFLAG_PUBLIC       (1<< 0) /* is a public function */
  490. #define AMIPRAGFLAG_A6USE        (1<< 1) /* A6 is used for this function */
  491. #define AMIPRAGFLAG_A5USE        (1<< 2) /* A5 is used */
  492. #define AMIPRAGFLAG_A4USE        (1<< 3) /* A4 is used */
  493. #define AMIPRAGFLAG_D7USE        (1<< 4) /* D7 is used */
  494. #define AMIPRAGFLAG_ARGCOUNT     (1<< 5) /* when double args, ... */
  495. #define AMIPRAGFLAG_DIDARGWARN   (1<< 6) /* We printed a argcount warning */
  496. #define AMIPRAGFLAG_FLOATARG     (1<< 7) /* It has a float argument */
  497. #define AMIPRAGFLAG_DIDFLOATWARN (1<< 8) /* We printed a float warning */
  498. #define AMIPRAGFLAG_NOCLIB       (1<< 9) /* No clib definition found */
  499. #define AMIPRAGFLAG_CLIBARGCNT   (1<<10) /* CLIB argument count error */
  500. #define AMIPRAGFLAG_PPC          (1<<11) /* This is an PPC function */
  501. #define AMIPRAGFLAG_PPC0         (1<<12) /* type PPC0 */
  502. #define AMIPRAGFLAG_PPC2         (1<<13) /* type PPC2 */
  503. #define AMIPRAGFLAG_M68K         (1<<14) /* This is an M68K function */
  504. #define AMIPRAGFLAG_OWNTAGFUNC   (1<<15) /* MakeTagFunction create tag */
  505.  
  506. struct AmiArgs {
  507.   strptr                         ArgName;
  508.   uint16                         ArgReg;
  509. };
  510.  
  511. #define NUMALIASNAMES            5
  512.  
  513. struct AmiPragma {
  514.   struct ShortList               List;
  515.   uint32                         Line;
  516.   uint32                         Flags;
  517.   strptr                         FuncName;
  518.   strptr                         TagName;
  519.   struct Pragma_AliasName *      AliasName[NUMALIASNAMES]; /* possible alias names */
  520.   uint16                         NumArgs;  /* register numbers */
  521.   uint16                         CallArgs; /* argument number in fd file */
  522.   int16                          Bias;
  523.   int8                           NumAlias;
  524.   int8                           Abi;
  525.   struct AmiArgs                 Args[MAXREGPPC];
  526. };
  527.  
  528. struct Comment {
  529.   struct ShortList       List;
  530.   strptr                 Data;
  531.   int16                  Bias;
  532.   uint16                 ReservedNum;
  533.   uint16                 Version;
  534.   uint8                  Private; /* is a flag only */
  535. };
  536.  
  537. struct Include {
  538.   struct ShortList       List;
  539.   strptr                 Include;
  540. };
  541.  
  542. struct PragList {
  543.   struct ShortList      List;
  544.   struct ShortListRoot  Data;        /* contains list of PragData */
  545.   strptr                Basename;
  546. };
  547.  
  548. struct PragData {
  549.   struct ShortList      List;
  550.   struct ShortListRoot  Name;
  551.   uint32                NumNames;
  552.   uint32                Bias;
  553.   uint32                NumArgs;
  554.   uint8                 ArgReg[MAXREG];
  555. };
  556.  
  557. struct FDData {
  558.   strptr Name;
  559.   strptr Basename;
  560.   uint32 Bias;
  561.   uint32 Mode;         /* 0 = Normal, != 0 is TagName */
  562.   uint32 NumArgs;
  563.   uint8  ArgReg[MAXREG];
  564. };
  565.  
  566. /* These CPP types match the strings used for CPP name creation. The
  567. defines are used both for name creation and type specification. */
  568. #define CPP_TYPE_VOID           'v'     /* void,   VOID    */
  569. #define CPP_TYPE_BYTE           'c'     /* char,   int8    */
  570. #define CPP_TYPE_WORD           's'     /* short,  int16    */
  571. #define CPP_TYPE_LONG           'j'     /* long,   int32    */
  572. #define CPP_TYPE_FLOAT          'f'     /* float,  FLOAT   */
  573. #define CPP_TYPE_DOUBLE         'd'     /* double, DOUBLE  */
  574. #define CPP_TYPE_INT            'i'     /* int */
  575. #define CPP_TYPE_STRUCTURE      0
  576. #define CPP_TYPE_VARARGS        'e'
  577.  
  578. /* These types are for string creation only. */
  579. #define CPP_TYPE_ENUM           'E'
  580. #define CPP_TYPE_CONST          'C'
  581. #define CPP_TYPE_FUNCTION       'F'
  582. #define CPP_TYPE_POINTER        'P'
  583. #define CPP_TYPE_UNSIGNED       'U'
  584. #define CPP_TYPE_FUNCEND        'p'
  585. #define CPP_TYPE_REGISTER       'r'
  586.  
  587. /* Some flags to be used in CPP_NameType->Flags. */
  588. #define CPP_FLAG_UNSIGNED       (1<<0) /* is an unsigned variable */
  589. #define CPP_FLAG_CONST          (1<<1) /* type is const */
  590. #define CPP_FLAG_STRPTR         (1<<2) /* this variable contains a strptr */
  591. #define CPP_FLAG_POINTER        (1<<3) /* the variable is a pointer */
  592. #define CPP_FLAG_ENUM           (1<<4) /* it is a enumeration */
  593. #define CPP_FLAG_STRUCT         (1<<5) /* it is a structure */
  594. #define CPP_FLAG_UNION          (1<<6) /* it is a union */
  595. #define CPP_FLAG_FUNCTION       (1<<7) /* it is a function */
  596. #define CPP_FLAG_BOOLEAN        (1<<8) /* in truth this element is bool */
  597. #define CPP_FLAG_REGISTER       (1<<9) /* argument is register type */
  598. #define CPP_FLAG_TYPEDEFNAME    (1<<10) /* name is created from typedef */
  599. #define CPP_FLAG_ARRAY          (1<<11) /* this type is an array */
  600. /* STRPTR is defined different under C and CPP -> I have to create two
  601. names, one time unsigned char *, one time signed char *, when somewhere
  602. a STRPTR occurs */
  603.  
  604. #define COPYCPP_PASSES          4
  605.  
  606. struct CPP_NameType { /* structure to describe a argument type */
  607.   strptr StructureName;     /* if a structure or enum only                */
  608.   strptr FuncArgs;          /* arguments of function - unterminated       */
  609.   strptr TypeStart;         /* start of this type                         */
  610.   strptr Replace;           /* replacement of type for SFD files          */
  611.   strptr Unknown;           /* unknown type handled as int                */
  612.   strptr FunctionName;      /* Argument name of function argument         */
  613.   struct ClibData *FuncPtr; /* if it is a function pointer                */
  614.   uint16 StructureLength;   /* length of the structure name               */
  615.   uint16 ArgsLength;        /* length of FuncArgs                         */
  616.   uint16 TypeLength;        /* length of this type                        */
  617.   uint16 FullLength;        /* length of complete type                    */
  618.   uint16 PointerDepth;      /* number of * in type                        */
  619.   uint16 FuncPointerDepth;  /* number of * in function pointer            */
  620.   uint16 Flags;             /* see above flags                            */
  621.   uint8  Type;              /* see above defines                          */
  622.   uint8  Register;          /* register number                            */
  623. };
  624.  
  625. struct ClibData { /* structure to describe data in CLIB file */
  626.   struct ClibData *     Next;         /* The next entry in this list */
  627.   strptr                FuncName;     /* name of the function */
  628.   struct CPP_NameType   ReturnType;   /* data for return type */
  629.   struct CPP_NameType   Args[MAXREGPPC+1]; /* data for argument types */
  630.   uint16                NumArgs;      /* number of arguments */
  631. };
  632.  
  633. struct CPP_ExternNames { /* structure for EXTTYPESFILE data */
  634.   struct CPP_ExternNames * Next;        /* The next entry in this list */
  635.   strptr                   Type;        /* The unknown type */
  636.   struct CPP_NameType      NameType;    /* The replacement */
  637. };
  638.  
  639. struct CPP_TypeField {  /* structure for internal defined types */
  640.   strptr Text;          /* name of the type */ 
  641.   uint16 Length;        /* length of the name string */
  642.   uint16 Flags;         /* CPP_FLAG flags */
  643.   uint8  Type;          /* CPP_TYPE value */
  644. };
  645.  
  646. struct CPP_Unknown {
  647.   struct CPP_Unknown *Next;
  648.   strptr              Unknown;
  649. };
  650.  
  651. struct Proto_LibType {  /* structure to define structure type of base vars */
  652.   strptr BaseName;      /* name of the library base */
  653.   strptr StructureName; /* name of the structure to be used (maybe 0 for default) */
  654.   strptr LibraryName;   /* name of the library (maybe 0 for default method) */
  655.   strptr ShortBaseName; /* short name of the library base */
  656. };
  657.  
  658. struct Pragma_ExecpName { /* structure to specify special tagnames */
  659.   strptr FunctionName;  /* function name */
  660.   strptr TagName;       /* tag name to be used for this function */
  661. }; /* TagName 0 is valid as well to disable tagfunctions */
  662.  
  663. struct Pragma_AliasName {
  664.   strptr FunctionName;
  665.   strptr AliasName;
  666.   uint32 Type;
  667. };
  668.  
  669. #define NTP_NORMAL      0    /* no tags/args    */
  670. #define NTP_TAGS        1    /* TagFunction     */
  671. #define NTP_ARGS        2    /* ArgFunction     */
  672. #define NTP_UNKNOWN     3    /* CommentFunction */
  673.  
  674. struct NameList {
  675.   struct ShortList      List;
  676.   uint32                Type;    /* set by OptimizeFDData */
  677.   strptr                NormName;
  678.   strptr                PragName;
  679. };
  680.  
  681. struct InFile {
  682.   strptr pos;
  683.   strptr buf;
  684.   size_t size;
  685. };
  686.  
  687. /* EHF definitions! */
  688. #define HUNK_PPC_CODE   0x4E9
  689. #define HUNK_RELRELOC26 0x4EC
  690. #define EXT_RELREF26    229
  691.  
  692. /* ------------------------------------------------------------------ */
  693. /* A short set of ELF definitions, see pasm sources in vbcc release for an
  694. more complete set of stuff or get elf documentation. These are needed for
  695. VBCCPUPCode function. */
  696. #define ELFCLASS32      1
  697. #define ELFDATA2MSB     2
  698. #define EV_CURRENT      1       /* version information */
  699. #define ET_REL          1       /* type information */
  700. #define EM_POWERPC      20
  701.  
  702. #define SHT_NULL        0       /* inactive */
  703. #define SHT_PROGBITS    1       /* program information */
  704. #define SHT_SYMTAB      2       /* symbol table */
  705. #define SHT_STRTAB      3       /* string table */
  706. #define SHT_RELA        4       /* relocation */
  707.  
  708. #define SHF_ALLOC       0x2     /* needs memory when started */
  709. #define SHF_EXECINSTR   0x4     /* executable instructions */
  710.  
  711. #define SHN_ABS         0xFFF1
  712.  
  713. #define EI_NIDENT       16
  714. #define EI_MAG0         0
  715. #define EI_MAG1         1
  716. #define EI_MAG2         2
  717. #define EI_MAG3         3
  718. #define EI_CLASS        4
  719. #define EI_DATA         5
  720. #define EI_VERSION      6
  721.  
  722. #define STB_LOCAL       0
  723. #define STB_GLOBAL      1
  724. #define STT_FUNC        2
  725. #define STT_NOTYPE      0
  726. #define STT_SECTION     3
  727. #define STT_FILE        4
  728. #define ELF32_ST_INFO(b,t)      (((b)<<4)+((t)&0xf))
  729. #define ELF32_R_INFO(s,t)       (((s)<<8)+(uint8)(t))
  730.  
  731. #define R_PPC_ADDR16_LO  4
  732. #define R_PPC_ADDR16_HA  6
  733. #define R_PPC_REL24     10
  734. #define R_PPC_SDAREL16  32
  735.  
  736. struct ArHeader {
  737.   string ar_name[16];             /* name */
  738.   string ar_time[12];             /* modification time */
  739.   string ar_uid[6];               /* user id */
  740.   string ar_gid[6];               /* group id */
  741.   string ar_mode[8];              /* octal file permissions */
  742.   string ar_size[10];             /* size in bytes */
  743.   string ar_fmag[2];              /* consistency check */
  744. };
  745.  
  746. /* AmigaOS hunk structure definitions */
  747. #define HUNK_UNIT       999
  748. #define HUNK_NAME       1000
  749. #define HUNK_CODE       1001
  750. #define HUNK_BSS        1003
  751. #define HUNK_ABSRELOC32 1004
  752. #define HUNK_EXT        1007
  753. #define HUNK_SYMBOL     1008
  754. #define HUNK_END        1010
  755. #define HUNK_DREL16     1016
  756.  
  757. #define EXT_DEF         1       /* normal definition */
  758. #define EXT_ABS         2       /* Absolute definition */
  759. #define EXT_REF32       129     /* 32 bit absolute reference to symbol */
  760. #define EXT_DEXT16      134     /* 16 bit data relative reference */
  761. /* ------------------------------------------------------------------ */
  762.  
  763. static struct Args             args            = {0,0,0,0,6,0};
  764. static struct InFile           in              = {0,0,0};
  765. static FILE *                  outfile;
  766. static struct ClibData *       clibdata        = 0;
  767. static struct ShortListRoot    AmiPragma       = {0,0,sizeof(struct AmiPragma)},
  768.                                Comment         = {0,0,sizeof(struct Comment)},
  769.                                Includes        = {0,0,sizeof(struct Include)};
  770. static struct CPP_ExternNames *extnames        = 0;
  771. static struct CPP_Unknown     *unknown         = 0;
  772. static strptr                  BaseName        = 0; /* the correct basename */
  773. static strptr                  ShortBaseName   = 0; /* the filename part of basename without Base */
  774. static strptr                  ShortBaseNameUpper = 0; /* like ShortBaseName, but upper case */
  775. static strptr                  HEADER          = 0;
  776. static strptr                  Copyright       = 0;
  777. static strptr                  filenamefmt     = 0;
  778. static strptr                  libtype         = 0;
  779. static strptr                  libname         = 0;
  780. static strptr                  defabi          = 0;
  781. static strptr                  hunkname        = ".text";
  782. static strptr                  datahunkname    = "__MERGED";
  783. static strptr                  PPCRegPrefix    = "r";
  784. static strptr                  IDstring        = 0;
  785. static strptr                  prefix          = "";
  786. static strptr                  subprefix       = "";
  787. static strptr                  premacro        = "";
  788. static uint8 *                 tempbuf         = 0;
  789. static size_t                  headersize      = 0;
  790. static uint32                  Flags           = 0;
  791. static uint32                  Flags2          = 0;
  792. static uint32                  Output_Error    = 1; /* Output error occured when 0 */
  793. static uint32                  tagfuncs        = 0; /* are there some tagfuncs in FD */
  794. static uint32                  priority        = 5; /* priority for auto libopen */
  795. static string                  filename[255];       /* needed for filename */
  796.  
  797. static int32                   LastBias        = 0; /* Only for E-Stuff, FD, SFD creation */
  798. static uint8 *                 elfbufpos       = 0; /* Only for PPC-LVO Lib's */
  799. static uint32                  symoffset       = 0; /* Only for PPC-LVO Lib's */
  800. static uint32                  CurrentABI      = 0; /* Only for FD, SFD creation */
  801.  
  802. /* Prototypes for the functions */
  803. static strptr  DupString(strptr, size_t);
  804. static strptr  AllocListMem(size_t);
  805. static strptr  SkipBlanks(strptr);
  806. static strptr  SkipBlanksRet(strptr);
  807. static strptr  SkipName(strptr);
  808. static uint32  GetTypes(void);
  809. static strptr  GetBaseType(void);
  810. static strptr  GetBaseTypeLib(void);
  811. static strptr  GetLibraryName(void);
  812. static int32   MakeShortBaseName(void);
  813. static uint32  OpenDest(strptr);
  814. static uint32  CloseDest(strptr);
  815. static uint32  MakeTagFunction(struct AmiPragma *);
  816. static void    MakeLines(strptr, uint32);
  817. static uint32  SpecialFuncs(void);
  818. static void    SortFDList(void);
  819. static void    AddAliasName(struct AmiPragma *, struct Pragma_AliasName *, uint32);
  820. static uint32  CheckNames(struct AmiPragma *);
  821. static uint32  ScanSFDFile(uint32);
  822. static uint32  ScanFDFile(void);
  823. static int32   ScanTypes(strptr, uint32);
  824. static void    FindHeader(void);
  825. static uint32  GetRegisterData(struct AmiPragma *);
  826. static uint16  GetFRegisterData(struct AmiPragma *);
  827. static uint32  OutputXDEF(uint32, strptr, ...);
  828. static uint32  OutputXREF(uint32, uint32, strptr, ...);
  829. static uint32  OutputXREF2(uint32, uint32, uint32, strptr, ...);
  830. static uint32  OutputSYMBOL(uint32, strptr, ...);
  831. static uint8 * AsmStackCopy(uint8 *, struct AmiPragma *, uint32, uint32);
  832. /* ------------------------------------------------------------------ */
  833. static void    DoError(uint32, uint32, ...);
  834. static uint32  CheckError(struct AmiPragma *, uint32);
  835. static uint32  DoOutputDirect(void *, size_t);
  836.  
  837. #if defined(__GNUC__)
  838. static uint32  DoOutput(strptr, ...) __attribute__ ((format(printf, 1, 2)));
  839. #else
  840. static uint32  DoOutput(strptr, ...);
  841. #endif
  842. /* ------------------------------------------------------------------ */
  843. static struct ShortList *NewItem(struct ShortListRoot *);
  844. static struct ShortList *RemoveItem(struct ShortListRoot *, struct ShortList *);
  845. static void              AddItem(struct ShortListRoot *, struct ShortList *);
  846. /* ------------------------------------------------------------------ */
  847. typedef uint32 (*FuncType)(struct AmiPragma *, uint32, strptr);
  848.  
  849. uint32 FuncAMICALL         (struct AmiPragma *, uint32, strptr);
  850. uint32 FuncLIBCALL         (struct AmiPragma *, uint32, strptr);
  851. uint32 FuncAsmText         (struct AmiPragma *, uint32, strptr);
  852. uint32 FuncAsmCode         (struct AmiPragma *, uint32, strptr);
  853. uint32 FuncCSTUBS          (struct AmiPragma *, uint32, strptr);
  854. uint32 FuncLVOXDEF         (struct AmiPragma *, uint32, strptr);
  855. uint32 FuncLVO             (struct AmiPragma *, uint32, strptr);
  856. uint32 FuncLVOPPCXDEF      (struct AmiPragma *, uint32, strptr);
  857. uint32 FuncLVOPPC          (struct AmiPragma *, uint32, strptr);
  858. uint32 FuncLVOPPCBias      (struct AmiPragma *, uint32, strptr);
  859. uint32 FuncLVOPPCName      (struct AmiPragma *, uint32, strptr);
  860. uint32 FuncLVOLib          (struct AmiPragma *, uint32, strptr);
  861. uint32 FuncLocCode         (struct AmiPragma *, uint32, strptr);
  862. uint32 FuncLocText         (struct AmiPragma *, uint32, strptr);
  863. uint32 FuncInline          (struct AmiPragma *, uint32, strptr);
  864. uint32 FuncInlineDirect    (struct AmiPragma *, uint32, strptr);
  865. uint32 FuncInlineNS        (struct AmiPragma *, uint32, strptr);
  866. uint32 FuncPowerUP         (struct AmiPragma *, uint32, strptr);
  867. uint32 FuncFPCUnit         (struct AmiPragma *, uint32, strptr);
  868. uint32 FuncFPCType         (struct AmiPragma *, uint32, strptr);
  869. uint32 FuncBMAP            (struct AmiPragma *, uint32, strptr);
  870. uint32 FuncVBCCInline      (struct AmiPragma *, uint32, strptr);
  871. uint32 FuncVBCCWOSInline   (struct AmiPragma *, uint32, strptr);
  872. uint32 FuncVBCCMorphInline (struct AmiPragma *, uint32, strptr);
  873. uint32 FuncVBCCWOSText     (struct AmiPragma *, uint32, strptr);
  874. uint32 FuncVBCCWOSCode     (struct AmiPragma *, uint32, strptr);
  875. uint32 FuncVBCCPUPText     (struct AmiPragma *, uint32, strptr);
  876. uint32 FuncVBCCPUPCode     (struct AmiPragma *, uint32, strptr);
  877. uint32 FuncEModule         (struct AmiPragma *, uint32, strptr);
  878. uint32 FuncVBCCMorphText   (struct AmiPragma *, uint32, strptr);
  879. uint32 FuncVBCCMorphCode   (struct AmiPragma *, uint32, strptr);
  880. uint32 FuncFD              (struct AmiPragma *, uint32, strptr);
  881. uint32 FuncClib            (struct AmiPragma *, uint32, strptr);
  882. uint32 FuncSFD             (struct AmiPragma *, uint32, strptr);
  883. uint32 FuncGateStubs       (struct AmiPragma *, uint32, strptr);
  884. static uint32 PrintComment (struct Comment *, strptr);
  885. static uint32 DoCallFunc   (struct AmiPragma *, uint32, strptr, FuncType);
  886. static uint32 CallFunc     (uint32, strptr, FuncType);
  887. static uint32 PrintIncludes(void);
  888. /* ------------------------------------------------------------------ */
  889. static int32   AddClibEntry(strptr, strptr, uint32);
  890. static int32   ScanClibFile(strptr, strptr);
  891. static int32   IsCPPType(struct CPP_NameType *, uint8);
  892. static uint32  CheckRegisterNum(strptr, struct CPP_NameType *);
  893. static uint32  ParseFuncPtrArgs(strptr, struct CPP_NameType *);
  894. static int32   GetCPPType(struct CPP_NameType *, strptr, uint32, uint32);
  895. static struct ClibData *GetClibFunc(strptr, struct AmiPragma *, uint32);
  896. static int32   CheckKeyword(strptr, strptr, int32);
  897. static uint32  CopyCPPType(strptr, uint32, struct ClibData *, struct AmiArgs *);
  898. static uint32  OutClibType(struct CPP_NameType *, strptr);
  899. static uint32  MakeClibType(strptr, struct CPP_NameType *, strptr);
  900. static uint32  OutPASCALType(struct CPP_NameType *, strptr, uint32);
  901. /* ------------------------------------------------------------------ */
  902. static uint32 CallPrag(uint32, strptr, FuncType);
  903. static uint32 CreatePragmaFile(strptr, strptr, strptr, strptr, uint32);
  904. static uint32 CreateCSTUBSFile(void);
  905. static uint32 CreateLVOFile(uint32);
  906. static uint32 CreateLVOFilePPC(uint32);
  907. static uint32 CreateAsmStubs(uint32, uint32);
  908. static uint32 CreateProtoFile(uint32);
  909. static uint32 CreateLocalData(strptr, uint32);
  910. static uint32 CreateInline(uint32, uint32);
  911. static uint32 CreateGateStubs(uint32);
  912. static uint32 CreateSASPowerUP(uint32);
  913. static uint32 CreateProtoPowerUP(void);
  914. static uint32 CreateFPCUnit(void);
  915. static uint32 CreateBMAP(void);
  916. static uint32 CreateLVOLib(void);
  917. static uint32 CreateLVOLibPPC(void);
  918. static uint32 CreateVBCCInline(uint32, uint32);
  919. static uint32 CreateVBCC(uint32, uint32);
  920. static uint32 CreateVBCCPUPLib(uint32);
  921. static uint32 CreateVBCCMorphCode(uint32);
  922. static uint32 CreateEModule(uint32);
  923. static uint32 CreateProtoRedirect(void);
  924. static uint32 CreateFD(void);
  925. static uint32 CreateSFD(uint32);
  926. static uint32 CreateClib(uint32);
  927. static uint32 CreateGenAuto(strptr, uint32);
  928. /* ------------------------------------------------------------------ */
  929. static uint32 GetName(struct NameList *, struct ShortListRoot *, uint32);
  930. static uint32 MakeFD(struct PragList *);
  931. static void   OptimizeFDData(struct PragData *);
  932. static string GetHexValue(string);
  933. static string GetDoubleHexValue(strptr);
  934. static uint32 AddFDData(struct ShortListRoot *, struct FDData *);
  935. static uint32 GetLibData(struct FDData *);
  936. static uint32 GetFlibData(struct FDData *);
  937. static uint32 GetAmiData(struct FDData *);
  938. static uint32 CreateFDFile(void);
  939. /* ------------------------------------------------------------------ */
  940. static void GetArgs(int argc, char **argv);
  941. static strptr mygetfile(strptr name, size_t *len);
  942.  
  943. #define ERROFFSET_CLIB  (1<<31)
  944.  
  945. enum {
  946. ERR_TAGFUNC_NEEDS_ARGUMENT,
  947. ERR_CANNOT_CONVERT_PRAGMA_TAGCALL,
  948. ERR_TAG_DEF_WITHOUT_PRAGMA,
  949. ERR_BASENAME_DECLARED_TWICE,
  950. ERR_EXPECTED_SLASH_IN_BASENAME,
  951. ERR_EXPECTED_BASENAME,
  952. ERR_EXPECTED_BIAS_VALUE,
  953. ERR_ASSUMING_POSITIVE_BIAS_VALUE,
  954. ERR_MISSING_FUNCTION_NAME,
  955. ERR_EXPECTED_OPEN_BRACKET,
  956. ERR_TO_MUCH_ARGUMENTS,
  957. ERR_EXPECTED_ARGUMENT_NAME,
  958. ERR_EXPECTED_CLOSE_BRACKET,
  959. ERR_EXPECTED_REGISTER_NAME,
  960. ERR_A7_NOT_ALLOWED,
  961. ERR_REGISTER_USED_TWICE,
  962. ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER,
  963. ERR_ASSUMING_BIAS_OF_30,
  964. ERR_EXTRA_CHARACTERS,
  965. ERR_MISSING_BASENAME,
  966. ERR_WRITING_FILE,
  967. ERR_EXPECTED_COMMA,
  968. ERR_DIFFERENT_TO_PREVIOUS,
  969. ERR_UNKNOWN_VARIABLE_TYPE,
  970. ERR_UNKNOWN_ERROR,
  971. ERR_MISSING_END,
  972. ERR_PROTOTYPE_MISSING,
  973. ERR_NOPROTOTYPES_FILE,
  974. ERR_UNKNOWN_DIRECTIVE,
  975. ERR_INLINE_A4_AND_A5,
  976. ERR_INLINE_D7_AND_A45,
  977. ERR_MISSING_SHORTBASENAME,
  978. ERR_A6_NOT_ALLOWED,
  979. ERR_EMPTY_FILE,
  980. ERR_FLOATARG_NOT_ALLOWED,
  981. ERR_WRONG_TYPES_LINE,
  982. ERR_LONG_DOUBLE,
  983. ERR_CLIB_ARG_COUNT,
  984. ERR_OPEN_FILE,
  985. ERR_A5_NOT_ALLOWED,
  986. ERR_PPC_FUNCTION_NOT_SUPPORTED,
  987. ERR_UNKNOWN_ABI,
  988. ERR_NO_SORTED,
  989. ERR_ILLEGAL_FUNCTION_POSITION,
  990. ERR_SORTED_COMMENT,
  991. ERR_COMMENT_SINGLEFILE,
  992. ERR_NOFD2PRAGMATYPES,
  993. ERR_M68K_FUNCTION_NOT_SUPPORTED,
  994. ERR_UNKNOWN_RETURNVALUE_TYPE,
  995. ERR_SFD_AND_CLIB,
  996. ERR_EXCPECTED_IDSTRING,
  997. ERR_EXPECTED_ID_ENDSIGN,
  998. ERR_MISSING_SFDEND,
  999. ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER,
  1000. ERR_IDSTRING_DECLARED_TWICE,
  1001. ERR_COMMANDLINE_LIBTYPE,
  1002. ERR_COMMANDLINE_BASENAME,
  1003. ERR_LIBTYPE_DECLARED_TWICE,
  1004. ERR_EXPECTED_LIBTYPE,
  1005. ERR_SORTED_SFD_FD,
  1006. ERR_EARLY_SHADOW,
  1007. ERR_DOUBLE_VARARGS,
  1008. ERR_VARARGS_ARGUMENTS_DIFFER,
  1009. ERR_UNEXPECTED_FILEEND,
  1010. ERR_VARARGS_ALIAS_FIRST,
  1011. ERR_ALIASNAMES,
  1012. ERR_EXPECTED_STRUCT,
  1013. ERR_EXPECTED_POINTERSIGN,
  1014. ERR_ARGNAME_KEYWORD_CONFLICT,
  1015. ERR_ARGNAME_ARGNAME_CONFLICT,
  1016. ERR_ONLYTAGMODE_NOTALLOWED,
  1017. ERR_COMMANDLINE_LIBNAME,
  1018. ERR_LIBNAME_DECLARED_TWICE,
  1019. ERR_EXPECTED_LIBNAME,
  1020. ERR_PREFIX,
  1021. ERR_MULTIPLEFUNCTION,
  1022. ERR_INLINE_AX_SWAPREG,
  1023. ERR_SFD_START,
  1024. ERR_ILLEGAL_CHARACTER_DETECTED,
  1025. ERR_UNKNOWN_VARIABLE_TYPE_INT,
  1026. ERR_UNKNOWN_RETURNVALUE_TYPE_INT,
  1027. };
  1028.  
  1029. static const struct ErrField {
  1030.   uint8  Type;    /* 0 = Error, 1 = Warning */
  1031.   uint8  Skip;
  1032.   strptr Error;
  1033. } Errors[] = {
  1034. {1, 1, "Tag function must have arguments."},
  1035. {1, 1, "Cannot convert pragma name into tag name."},
  1036. {1, 1, "Tag definition without preceding Pragma."},
  1037. {1, 0, "Basename declared twice."},
  1038. {1, 0, "Expected preceding _ in Basename."},
  1039. {1, 1, "Expected Basename."},
  1040. {1, 0, "Expected Bias value."},
  1041. {1, 0, "Assuming positive bias value."},
  1042. {1, 1, "Missing function name."},
  1043. {1, 1, "Expected '('."},
  1044. {1, 1, "Too much arguments."},
  1045. {1, 1, "Expected argument name."},
  1046. {1, 1, "Expected ')'."},
  1047. {1, 1, "Expected register name."},
  1048. {1, 1, "A7 not allowed as argument register."},
  1049. {1, 1, "Register used twice."},
  1050. {1, 0, "Number of arguments != number of registers."},
  1051. {1, 0, "Assuming bias of 30."},
  1052. {1, 1, "Extra characters."},
  1053. {0, 0, "Missing Basename in FD file."},
  1054. {0, 0, "Failed to write destination file."},
  1055. {1, 1, "Expected ','."},
  1056. {0, 1, "Data different to previous given."},
  1057. {1, 0, "Unknown type of argument %ld."},
  1058. {0, 0, "Unknown problem: program error or corrupt input data."},
  1059. {1, 0, "Missing ##end."},
  1060. {1, 0, "Prototype for function \"%s\" not found."},
  1061. {0, 0, "No prototypes file (CLIB parameter) was specified."},
  1062. {1, 1, "Unknown directive '%s' found."},
  1063. {1, 0, "Usage of both A4 and A5 is not supported."},
  1064. {1, 0, "Usage of both D7 and A4 or A5 is not supported."},
  1065. {0, 0, "Missing Basename in FD file and FD filename."},
  1066. {1, 0, "A6 not allowed as argument register."},
  1067. {1, 0, "Empty or partial file deleted."},
  1068. {1, 1, "Floating point arguments not allowed."},
  1069. {0, 0, "Wrong definition in external type definition file."},
  1070. {1, 0, "Cannot determine if FPU argument is double or single."},
  1071. {1, 0, "CLIB argument count differs for %s (%ld != %ld)."},
  1072. {0, 0, "Could not open file \"%s\"."},
  1073. {1, 0, "A5 cannot be used as argument register."},
  1074. {1, 0, "Format supports no PPC functions."},
  1075. {1, 0, "Unknown ABI '%s' found."},
  1076. {0, 0, "SORTED cannot be used with that type."},
  1077. {1, 0, "Position of function %s not supported with that type."},
  1078. {1, 1, "COMMENT and SORTED cannot be used both. Ignoring SORTED."},
  1079. {1, 0, "COMMENT cannot be used in single file mode, ignoring."},
  1080. {1, 0, "Missing the types definition file. Using internal defaults."},
  1081. {1, 0, "Format supports no M68k functions."},
  1082. {1, 0, "Unknown type of return value."},
  1083. {1, 0, "With SFD as input CLIB file is ignored."},
  1084. {1, 0, "Expected $Id: in ID string."},
  1085. {1, 0, "Expected $ at end of ID string."},
  1086. {1, 0, "Missing ==end."},
  1087. {1, 1, "Expected positive decimal number."},
  1088. {1, 0, "ID string declared twice."},
  1089. {1, 1, "Library type of commandline overwrites file settings."},
  1090. {1, 1, "Basename of commandline overwrites file settings."},
  1091. {1, 0, "Library type declared twice."},
  1092. {1, 1, "Expected library type definition."},
  1093. {1, 1, "SORTED cannot be used with SFD and FD output."},
  1094. {1, 0, "Function expected before ##shadow."},
  1095. {1, 1, "There is already a varargs function, handling as alias."},
  1096. {1, 0, "Varargs function cannot have different arguments."},
  1097. {1, 0, "Unexpected end of file."},
  1098. {1, 0, "Commands varargs and alias cannot be at file start."},
  1099. {1, 0, "Only %d alias names supported."},
  1100. {1, 1, "Expected struct keyword in library type."},
  1101. {1, 0, "Expected '*' at end of library type definition."},
  1102. {1, 1, "Name of argument %d conflicts with keyword '%s'."},
  1103. {1, 1, "Name of argument %d conflicts with argument %d."},
  1104. {1, 0, "SFD files cannot consist only of varargs functions."},
  1105. {1, 1, "Library name of commandline overwrites file settings."},
  1106. {1, 0, "Library name declared twice."},
  1107. {1, 1, "Expected library name definition."},
  1108. {1, 0, "Neither prefix nor subprefix specified."},
  1109. {1, 0, "Format supports single function pointer only (void * used)."},
  1110. {1, 0, "No swap register left for %s."},
  1111. {1, 0, "SFD files should always start with ==id directive."},
  1112. {1, 0, "Illegal character detected."},
  1113. {1, 0, "Unknown type of argument %ld (%s) handled as int."},
  1114. {1, 0, "Unknown type of return value (%s) handled as int."},
  1115. };
  1116.  
  1117. #ifdef __SASC
  1118. __far
  1119. #endif
  1120. static uint8 InternalTypes[] = {
  1121. "IX:struct InputXpression\n"
  1122. "Msg:struct ? *\n"
  1123. "Class:struct IClass\n"
  1124. "BootBlock:struct bootblock\n"
  1125. "ValidIDstruct:struct ValidIDstruct\n"
  1126. "DisplayInfoHandle:void *\n"
  1127. "RESOURCEFILE:void *\n"
  1128. "RESOURCEID:unsigned long\n"
  1129. "GLvoid:void\n"
  1130. "GLbitfield:unsigned long\n"
  1131. "GLbyte:signed char\n"
  1132. "GLshort:short\n"
  1133. "GLint:long\n"
  1134. "GLsizei:unsigned long\n"
  1135. "GLubyte:unsigned char\n"
  1136. "GLushort:unsigned short\n"
  1137. "GLuint:unsigned long\n"
  1138. "GLfloat:float\n"
  1139. "GLclampf:float\n"
  1140. "GLdouble:double\n"
  1141. "GLclampd:double\n"
  1142. "GLboolean:enum ?\n"
  1143. "GLenum:enum ?\n"
  1144. "GLlookAt:struct GLlookAt\n"
  1145. "GLproject:struct GLproject\n"
  1146. "GLunProject:struct GLunProject\n"
  1147. "GLfrustum:struct GLfrustum\n"
  1148. "GLortho:struct GLortho\n"
  1149. "GLbitmap:struct GLbitmap\n"
  1150. "GLUquadricObj:struct GLUquadricObj\n"
  1151. "GLUtriangulatorObj:struct GLUtriangulatorObj\n"
  1152. "GLUnurbsObj:struct GLUnurbsObj\n"
  1153. "GLvisual:struct gl_visual\n"
  1154. "GLframebuffer:struct gl_frame_buffer\n"
  1155. "GLcontext:struct gl_context\n"
  1156. "HGIDA_Stack:unsigned long *\n"
  1157. "HGIDA_BoundedStack:unsigned long *\n"
  1158. "HGIDA_Queue:unsigned long *\n"
  1159. "HGIDA_BoundedQueue:unsigned long *\n"
  1160. "HGIDA_List:unsigned long *\n"
  1161. "HGIDA_ListItem:unsigned long *\n"
  1162. "HGIDA_Error:enum ?\n"
  1163. "HGIDA_Direction:enum ?\n"
  1164. "uid_t:long\n"
  1165. "gid_t:long\n"
  1166. "mode_t:unsigned short\n"
  1167. "pid_t:struct Task *\n"
  1168. "fd_set:struct fd_set\n"
  1169. "SerScriptCallback_t:unsigned long (*)(register __a0 void *, register __d0 unsigned long, register __a1 const unsigned char *, register __a2 struct CSource *, register __a3 struct CSource *)\n"
  1170. "pcap_t:struct pcap\n"
  1171. "pcap_dumper_t:struct pcap_dumper\n"
  1172. "pcap_handler:void (*)(unsigned char *, const struct pcap_pkthdr *, const unsigned char *)\n"
  1173. "u_char:unsigned char\n"
  1174. "bpf_u_int32:unsigned long\n"
  1175. "Fixed:long\n"
  1176. "sposition:long\n"
  1177. "MPEGA_STREAM:struct MPEGA_STREAM\n"
  1178. "MPEGA_CTRL:struct MPEGA_CTRL\n"
  1179. "W3D_Context:struct W3DContext\n"
  1180. "W3D_Driver:struct W3DDriver\n"
  1181. "W3D_Texture:struct W3DTexture\n"
  1182. "W3D_Scissor:struct W3DScissor\n"
  1183. "W3D_Line:struct W3D_Line\n"
  1184. "W3D_Point:struct W3D_Point\n"
  1185. "W3D_Triangle:struct W3D_Triangle\n"
  1186. "W3D_Triangles:struct W3D_Triangles\n"
  1187. "W3D_Float:float\n"
  1188. "W3D_Bitmap:struct W3D_Bitmap\n"
  1189. "W3D_Fog:struct W3D_Fog\n"
  1190. "W3D_Bool:short\n"
  1191. "W3D_Double:double\n"
  1192. "W3D_TriangleV:struct W3D_TriangleV\n"
  1193. "W3D_TrianglesV:struct W3D_TriangleV\n"
  1194. "W3D_ScreenMode:struct W3D_Screenmode\n"
  1195. "W3D_Color:struct W3D_Color\n"
  1196. "W3D_Lines:struct W3D_Lines\n"
  1197. "RGBFTYPE:enum ?\n"
  1198. "DITHERINFO:void *\n"
  1199. "SLayer:void *\n"
  1200. "va_list:char *\n"
  1201. "time_t:long\n"
  1202. "size_t:unsigned int\n"
  1203. "uint8:unsigned char\n"
  1204. "uint16:unsigned short\n"
  1205. "uint32:unsigned long\n"
  1206. "int8:char\n"
  1207. "int16:short\n"
  1208. "int32:long\n"
  1209. "AVLKey:void *\n"
  1210. "PtrBigNum:struct BigNum *\n"
  1211. "BF_KEY:struct bf_key_st\n"
  1212. "BF_LONG:unsigned long\n"
  1213. "CAST_KEY:struct cast_key_st\n"
  1214. "CAST_LONG:unsigned long\n"
  1215. "DES_LONG:unsigned long\n"
  1216. "des_key_schedule:struct des_ks_struct\n"
  1217. "const_des_cblock:unsigned char [8]\n"
  1218. "des_cblock:unsigned char [8]\n"
  1219. "IDEA_KEY_SCHEDULE:struct idea_key_st\n"
  1220. "MD2_CTX:struct MD2state_st\n"
  1221. "MD5_CTX:struct MD5state_st\n"
  1222. "MDC2_CTX:struct mdc2_ctx_st\n"
  1223. "RC2_KEY:struct rc2_key_st\n"
  1224. "RC4_KEY:struct rc4_key_st\n"
  1225. "RC5_32_KEY:struct rc5_key_st\n"
  1226. "RIPEMD160_CTX:struct RIPEMD160state_st\n"
  1227. "SHA_CTX:struct SHAstate_st\n"
  1228. "ASN1_CTX:struct asn1_ctx_st\n"
  1229. "ASN1_OBJECT:struct asn1_object_st\n"
  1230. "ASN1_STRING:struct asn1_string_st\n"
  1231. "ASN1_TYPE:struct asn1_type_st\n"
  1232. "ASN1_METHOD:struct asn1_method_st\n"
  1233. "ASN1_HEADER:struct asn1_header_st\n"
  1234. "ASN1_INTEGER:struct asn1_string_st\n"
  1235. "ASN1_ENUMERATED:struct asn1_string_st\n"
  1236. "ASN1_BIT_STRING:struct asn1_string_st\n"
  1237. "ASN1_OCTET_STRING:struct asn1_string_st\n"
  1238. "ASN1_PRINTABLESTRING:struct asn1_string_st\n"
  1239. "ASN1_T61STRING:struct asn1_string_st\n"
  1240. "ASN1_IA5STRING:struct asn1_string_st\n"
  1241. "ASN1_UTCTIME:struct asn1_string_st\n"
  1242. "ASN1_GENERALIZEDTIME:struct asn1_string_st\n"
  1243. "ASN1_TIME:struct asn1_string_st\n"
  1244. "ASN1_GENERALSTRING:struct asn1_string_st\n"
  1245. "ASN1_UNIVERSALSTRING:struct asn1_string_st\n"
  1246. "ASN1_BMPSTRING:struct asn1_string_st\n"
  1247. "ASN1_VISIBLESTRING:struct asn1_string_st\n"
  1248. "ASN1_UTF8STRING:struct asn1_string_st\n"
  1249. "BIO:struct bio_st\n"
  1250. "BIO_F_BUFFER_CTX:struct bio_f_buffer_ctx_struct\n"
  1251. "BIO_METHOD:struct bio_method_st\n"
  1252. "BIGNUM:struct bignum_st\n"
  1253. "BN_CTX:struct bignum_ctx\n"
  1254. "BN_ULONG:unsigned long\n"
  1255. "BN_MONT_CTX:struct bn_mont_ctx_st\n"
  1256. "BN_BLINDING:struct bn_blinding_st\n"
  1257. "BN_RECP_CTX:struct bn_recp_ctx_st\n"
  1258. "BUF_MEM:struct buf_mem_st\n"
  1259. "COMP_METHOD:struct comp_method_st\n"
  1260. "COMP_CTX:struct comp_ctx_st\n"
  1261. "CONF_VALUE:struct !\n"
  1262. "LHASH_NODE:struct lhash_node_st\n"
  1263. "LHASH:struct lhash_st\n"
  1264. "CRYPTO_EX_DATA:struct crypto_ex_data_st\n"
  1265. "CRYPTO_EX_DATA_FUNCS:struct crypto_ex_data_func_st\n"
  1266. "DH:struct dh_st\n"
  1267. "DSA:struct dsa_st\n"
  1268. "DSA_SIG:struct DSA_SIG_st\n"
  1269. "ERR_STATE:struct err_state_st\n"
  1270. "ERR_STRING_DATA:struct ERR_string_data_st\n"
  1271. "EVP_PKEY:struct evp_pkey_st\n"
  1272. "EVP_MD:struct env_md_st\n"
  1273. "EVP_MD_CTX:struct env_md_ctx_st\n"
  1274. "EVP_CIPHER:struct evp_cipher_st\n"
  1275. "EVP_CIPHER_INFO:struct evp_cipher_info_st\n"
  1276. "EVP_CIPHER_CTX:struct evp_cipher_ctx_st\n"
  1277. "EVP_ENCODE_CTX:struct evp_Encode_Ctx_st\n"
  1278. "EVP_PBE_KEYGEN:struct int (*)(struct evp_cipher_ctx_st *ctx, const char *pass, int passlen, struct asn1_type_st *param, struct evp_cipher_st *cipher, struct env_md_st *md, int en_de)\n"
  1279. "HMAC_CTX:struct hmac_ctx_st\n"
  1280. "OBJ_NAME:struct obj_name_st\n"
  1281. "PEM_ENCODE_SEAL_CTX:struct PEM_Encode_Seal_st\n"
  1282. "PEM_USER:struct pem_recip_st\n"
  1283. "PEM_CTX:struct pem_ctx_st\n"
  1284. "PKCS12_MAC_DATA:struct !\n"
  1285. "PKCS12:struct !\n"
  1286. "PKCS12_SAFEBAG:struct !\n"
  1287. "PKCS12_BAGS:struct pkcs12_bag_st\n"
  1288. "PKCS7_ISSUER_AND_SERIAL:struct pkcs7_issuer_and_serial_st\n"
  1289. "PKCS7_SIGNER_INFO:struct pkcs7_signer_info_st\n"
  1290. "PKCS7_RECIP_INFO:struct pkcs7_recip_info_st\n"
  1291. "PKCS7_SIGNED:struct pkcs7_signed_st\n"
  1292. "PKCS7_ENC_CONTENT:struct pkcs7_enc_content_st\n"
  1293. "PKCS7_ENVELOPE:struct pkcs7_enveloped_st\n"
  1294. "PKCS7_SIGN_ENVELOPE:struct pkcs7_signedandenveloped_st\n"
  1295. "PKCS7_DIGEST:struct pkcs7_digest_st\n"
  1296. "PKCS7_ENCRYPT:struct pkcs7_encrypted_st\n"
  1297. "PKCS7:struct pkcs7_st\n"
  1298. "RAND_METHOD:struct rand_meth_st\n"
  1299. "RSA:struct rsa_st\n"
  1300. "RSA_METHOD:struct rsa_meth_st\n"
  1301. "TXT_DB:struct txt_db_st\n"
  1302. "X509_OBJECTS:struct X509_objects_st\n"
  1303. "X509_ALGOR:struct X509_algor_st\n"
  1304. "X509_VAL:struct X509_val_st\n"
  1305. "X509_PUBKEY:struct X509_pubkey_st\n"
  1306. "X509_SIG:struct X509_sig_st\n"
  1307. "X509_NAME_ENTRY:struct X509_name_entry_st\n"
  1308. "X509_NAME:struct X509_name_st\n"
  1309. "X509_EXTENSION:struct X509_extension_st\n"
  1310. "X509_ATTRIBUTE:struct x509_attributes_st\n"
  1311. "X509_REQ_INFO:struct X509_req_info_st\n"
  1312. "X509_REQ:struct X509_req_st\n"
  1313. "X509_CINF:struct x509_cinf_st\n"
  1314. "X509:struct x509_st\n"
  1315. "X509_REVOKED:struct X509_revoked_st\n"
  1316. "X509_CRL_INFO:struct X509_crl_info_st\n"
  1317. "X509_CRL:struct X509_crl_st\n"
  1318. "X509_PKEY:struct private_key_st\n"
  1319. "X509_INFO:struct X509_info_st\n"
  1320. "NETSCAPE_SPKAC:struct Netscape_spkac_st\n"
  1321. "NETSCAPE_SPKI:struct Netscape_spki_st\n"
  1322. "NETSCAPE_CERT_SEQUENCE:struct Netscape_certificate_sequence\n"
  1323. "CBC_PARAM:struct CBCParameter_st\n"
  1324. "PBEPARAM:struct PBEPARAM_st\n"
  1325. "PBE2PARAM:struct PBE2PARAM_st\n"
  1326. "PBKDF2PARAM:struct PBKDF2PARAM_st\n"
  1327. "PKCS8_PRIV_KEY_INFO:struct pkcs8_priv_key_info_st\n"
  1328. "X509V3_CONF_METHOD:struct X509V3_CONF_METHOD_st\n"
  1329. "X509V3_EXT_METHOD:struct v3_ext_method\n"
  1330. "X509V3_CTX:struct v3_ext_ctx\n"
  1331. "X509_HASH_DIR_CTX:struct x509_hash_dir_st\n"
  1332. "X509_CERT_FILE_CTX:struct x509_file_st\n"
  1333. "X509_OBJECT:struct X509_objects_st\n"
  1334. "X509_LOOKUP:struct x509_lookup_st\n"
  1335. "X509_LOOKUP_METHOD:struct x509_lookup_method_st\n"
  1336. "X509_STORE_CTX:struct x509_store_state_st\n"
  1337. "X509_STORE:struct x509_store_st\n"
  1338. "BIT_STRING_BITNAME:struct BIT_STRING_BITNAME_st\n"
  1339. "BASIC_CONSTRAINTS:struct BASIC_CONSTRAINTS_st\n"
  1340. "PKEY_USAGE_PERIOD:struct PKEY_USAGE_PERIOD_st\n"
  1341. "GENERAL_NAME:struct GENERAL_NAME_st\n"
  1342. "DIST_POINT_NAME:struct DIST_POINT_NAME_st\n"
  1343. "DIST_POINT:struct DIST_POINT_st\n"
  1344. "AUTHORITY_KEYID:struct AUTHORITY_KEYID_st\n"
  1345. "SXNETID:struct SXNET_ID_st\n"
  1346. "SXNET:struct SXNET_st\n"
  1347. "NOTICEREF:struct NOTICEREF_st\n"
  1348. "USERNOTICE:struct USERNOTICE_st\n"
  1349. "POLICYQUALINFO:struct POLICYQUALINFO_st\n"
  1350. "POLICYINFO:struct POLICYINFO_st\n"
  1351. "pem_password_cb:int (*)(char *buf, int size, int rwflag, void *userdata)\n"
  1352. "SSL_CIPHER:struct ssl_cipher_st\n"
  1353. "SSL:struct ssl_st\n"
  1354. "SSL_CTX:struct ssl_ctx_st\n"
  1355. "SSL_METHOD:struct ssl_method_st\n"
  1356. "SSL_SESSION:struct ssl_session_st\n"
  1357. "SSL_COMP:struct ssl_comp_st\n"
  1358. "SSL2_CTX:struct ssl2_ctx_st\n"
  1359. "SSL3_RECORD:struct ssl3_record_st\n"
  1360. "SSL3_BUFFER:struct ssl3_buffer_st\n"
  1361. "SSL3_CTX:struct ssl3_ctx_st\n"
  1362. "CERT_PKEY:struct cert_pkey_st\n"
  1363. "CERT:struct cert_st\n"
  1364. "SESS_CERT:struct sess_cert_st\n"
  1365. "SSL3_ENC_METHOD:struct ssl3_enc_method\n"
  1366. "SSL3_COMP:struct ssl3_comp_st\n"
  1367. "STACK_OF(X509_ATTRIBUTE):struct stack_st_X509_ATTRIBUTE\n"
  1368. "STACK_OF(X509_INFO):struct stack_st_X509_INFO\n"
  1369. "STACK_OF(X509_NAME):struct stack_st_X509_NAME\n"
  1370. "STACK_OF(X509):struct stack_st_X509\n"
  1371. "STACK_OF(PKCS7_SIGNER_INFO):struct stack_st_PKCS7_SIGNER_INFO\n"
  1372. "STACK_OF(SSL_CIPHER):struct stack_st_SSL_CIPHER\n"
  1373. "STACK_OF(GENERAL_NAME):struct stack_st_GENERAL_NAME\n"
  1374. "STACK_OF(CONF_VALUE):struct stack_st_CONF_VALUE\n"
  1375. "STACK_OF(ASN1_OBJECT):struct stack_st_ASN1_OBJECT\n"
  1376. "STACK_OF(POLICYINFO):struct stack_st_POLICYINFO\n"
  1377. "STACK_OF(DIST_POINT):struct stack_st_DIST_POINT\n"
  1378. "STACK_OF(X509_EXTENSION):struct stack_st_X509_EXTENSION\n"
  1379. "STACK:struct stack_st\n"
  1380. };
  1381.  
  1382. static const struct CPP_TypeField CPP_Field[] = {
  1383. {"int",         3, 0,                                  CPP_TYPE_INT},
  1384. {"long",        4, 0,                                  CPP_TYPE_LONG},
  1385. {"LONG",        4, 0,                                  CPP_TYPE_LONG},
  1386. {"BPTR",        4, 0,                                  CPP_TYPE_LONG},
  1387. {"BSTR",        4, 0,                                  CPP_TYPE_LONG},
  1388. {"CxObj",       5, 0,                                  CPP_TYPE_LONG},
  1389. {"CxMsg",       5, 0,                                  CPP_TYPE_LONG},
  1390. {"ULONG",       5, CPP_FLAG_UNSIGNED,                  CPP_TYPE_LONG},
  1391. {"LONGBITS",    8, CPP_FLAG_UNSIGNED,                  CPP_TYPE_LONG},
  1392. {"CPTR",        4, CPP_FLAG_UNSIGNED,                  CPP_TYPE_LONG},
  1393. {"Tag",         3, CPP_FLAG_UNSIGNED,                  CPP_TYPE_LONG},
  1394. {"Object",      6, CPP_FLAG_UNSIGNED,                  CPP_TYPE_LONG},
  1395. {"short",       5, 0,                                  CPP_TYPE_WORD},
  1396. {"SHORT",       5, 0,                                  CPP_TYPE_WORD},
  1397. {"COUNT",       5, 0,                                  CPP_TYPE_WORD},
  1398. {"WORD",        4, 0,                                  CPP_TYPE_WORD},
  1399. {"USHORT",      6, CPP_FLAG_UNSIGNED,                  CPP_TYPE_WORD},
  1400. {"UWORD",       5, CPP_FLAG_UNSIGNED,                  CPP_TYPE_WORD},
  1401. {"UCOUNT",      6, CPP_FLAG_UNSIGNED,                  CPP_TYPE_WORD},
  1402. {"WORDBITS",    8, CPP_FLAG_UNSIGNED,                  CPP_TYPE_WORD},
  1403. {"RPTR",        4, CPP_FLAG_UNSIGNED,                  CPP_TYPE_WORD},
  1404. {"BOOL",        4, CPP_FLAG_BOOLEAN,                   CPP_TYPE_WORD},
  1405. {"char",        4, 0,                                  CPP_TYPE_BYTE},
  1406. {"BYTE",        4, 0,                                  CPP_TYPE_BYTE},
  1407. {"UBYTE",       5, CPP_FLAG_UNSIGNED,                  CPP_TYPE_BYTE},
  1408. {"TEXT",        4, CPP_FLAG_UNSIGNED,                  CPP_TYPE_BYTE},
  1409. {"BYTEBITS",    8, CPP_FLAG_UNSIGNED,                  CPP_TYPE_BYTE},
  1410. {"float",       5, 0,                                  CPP_TYPE_FLOAT},
  1411. {"FLOAT",       5, 0,                                  CPP_TYPE_FLOAT},
  1412. {"double",      6, 0,                                  CPP_TYPE_DOUBLE},
  1413. {"DOUBLE",      6, 0,                                  CPP_TYPE_DOUBLE},
  1414. {"void",        4, 0,                                  CPP_TYPE_VOID},
  1415. {"VOID",        4, 0,                                  CPP_TYPE_VOID},
  1416. {"APTR",        4, CPP_FLAG_POINTER,                   CPP_TYPE_VOID},
  1417. {"STRPTR",      6, CPP_FLAG_POINTER|CPP_FLAG_STRPTR,   CPP_TYPE_BYTE},
  1418. {"CONST_STRPTR",12,CPP_FLAG_POINTER|CPP_FLAG_CONST,    CPP_TYPE_BYTE},
  1419. {"ClassID",     7, CPP_FLAG_POINTER|CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
  1420. {"PLANEPTR",    8, CPP_FLAG_POINTER|CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
  1421. {0,0,0,0},
  1422. };
  1423.  
  1424. /* defaults:                    "Library"               shortbname+".library"   basename-last 4 chars */
  1425. static const struct Proto_LibType Proto_LibTypes[] = {
  1426. {"DOSBase",                     "DosLibrary",           0,                      0},
  1427. {"SysBase",                     "ExecBase",             0,                      0},
  1428. {"ExpansionBase",               "ExpansionBase",        0,                      0},
  1429. {"GfxBase",                     "GfxBase",              "graphics.library",     "graphics"},
  1430. {"IntuitionBase",               "IntuitionBase",        0,                      0},
  1431. {"LocaleBase",                  "LocaleBase",           0,                      0},
  1432. {"MathIeeeDoubBasBase",         "MathIEEEBase",         0,                      0},
  1433. {"MathIeeeDoubTransBase",       "MathIEEEBase",         0,                      0},
  1434. {"MathIeeeSingBasBase",         "MathIEEEBase",         0,                      0},
  1435. {"MathIeeeSingTransBase",       "MathIEEEBase",         0,                      0},
  1436. {"RealTimeBase",                "RealTimeBase",         0,                      0},
  1437. {"RexxSysBase",                 "RxsLib",               0,                      0},
  1438. {"UtilityBase",                 "UtilityBase",          0,                      0},
  1439. {"WorkbenchBase",               0,                      "workbench.library",    "wb"},
  1440. /* resources - The Node entries may be correct, but I don't know it. */
  1441. {"BattClockBase",               0/*"Node"*/,            "battclock.resource",   0},
  1442. {"BattMemBase",                 0/*"Node"*/,            "battmem.resource",     0},
  1443. {"CardResource",                0/*"Node"*/,            "card.resource",        "cardres"},
  1444. {"DiskBase",                    "DiskResource",         "disk.resource",        0},
  1445. {"MiscBase",                    0/*"Node"*/,            "misc.resource",        0},
  1446. {"PotgoBase",                   0/*"Node"*/,            "potgo.resource",       0},
  1447. /* devices */
  1448. {"ConsoleDevice",               "Device",               "console.device",       "console"},
  1449. {"InputBase",                   "Device",               "input.device",         0},
  1450. {"RamdriveDevice",              "Device",               "ramdrive.device",      "ramdrive"},
  1451. {"TimerBase",                   "Device",               "timer.device",         0},
  1452. /* non default Basenames */
  1453. {"DatamasterBase",              "DatamasterBase",       0,                      0},
  1454. {"PPBase",                      "PPBase",               "powerpacker.library",  "powerpacker"},
  1455. {"ReqToolsBase",                "ReqToolsBase",         0,                      0},
  1456. {"UnpackBase",                  "UnpackLibrary",        0,                      0},
  1457. {"xfdMasterBase",               "xfdMasterBase",        0,                      0},
  1458. {"xadMasterBase",               "xadMasterBase",        0,                      0},
  1459. /*{"xvsBase",                     "xvsBase",              0,                      0}, now completely private */
  1460. {"GTXBase",                     "GTXBase",              "gadtoolsbox.library",  "gtx"},
  1461. {"ArpBase",                     "ArpBase",              0,                      0},
  1462. {"PopupMenuBase",               "PopupMenuBase",        0,                      "pm"},
  1463. {"PowerPCBase",                 "PPCBase",              0,                      0},
  1464. {0, 0},
  1465. };
  1466.  
  1467. /* CachePostDMA, CachePreDMA are done by #?DMA check */
  1468. static const struct Pragma_ExecpName Pragma_ExecpNames[] = {
  1469. {"VFWritef",                    "FWritef"},
  1470. {"VFPrintf",                    "FPrintf"},
  1471. {"VPrintf",                     "Printf"},
  1472. {"ReadArgs",                    0},
  1473. {"FreeArgs",                    0},
  1474. {"CloneTagItems",               0},
  1475. {"FindTagItem",                 0},
  1476. {"FreeTagItems",                0},
  1477. {"GetTagData",                  0},
  1478. {"PackBoolTags",                0},
  1479. {"PackStructureTags",           0},
  1480. {"UnpackStructureTags",         0},
  1481. {"BGUI_PackStructureTags",      0},
  1482. {"BGUI_UnpackStructureTags",    0},
  1483. {"Inet_NtoA",                   0}, /* socket.library */
  1484. {"vsyslog",                     "syslog"},
  1485. {"NewPPCStackSwap",             0},
  1486. {0,0},
  1487. };
  1488.  
  1489. /* For double tagcall names (currently only necessary for dos.library and
  1490. datatypes.library). Only one alias supported for a function! */
  1491. static const struct Pragma_AliasName Pragma_AliasNames[] = {
  1492. {"AllocDosObject",      "AllocDosObjectTagList",        FUNCFLAG_NORMAL},
  1493. {"CreateNewProc",       "CreateNewProcTagList",         FUNCFLAG_NORMAL},
  1494. {"NewLoadSeg",          "NewLoadSegTagList",            FUNCFLAG_NORMAL},
  1495. {"SystemTagList",       "System",                       FUNCFLAG_NORMAL},
  1496. {"RefreshDTObject",     "RefreshDTObjects",             FUNCFLAG_TAG},
  1497. {0,0,0},
  1498. };
  1499.  
  1500. /* special names, which get an x before name in BMAP files */
  1501. static const strptr BMAPSpecial[] =
  1502. {"abs", "Close", "Exit", "Input", "Open", "Output", "Read", "tan",
  1503. "Translate", "Wait", "Write", 0};
  1504.  
  1505. #define  FIRST_KNOWN_RELEASE    30
  1506. #define  LAST_KNOWN_RELEASE     45
  1507. static const strptr Release[] =
  1508. {
  1509.   "Release 1.0",                /* V30 */
  1510.   "Release 1.1",                /* V31 */
  1511.   "Preliminary Release 1.2",    /* V32 */
  1512.   "Release 1.2",                /* V33 */
  1513.   "Release 1.3",                /* V34 */
  1514.   "Release 1.3 A2024",          /* V35 */
  1515.   "Release 2.0",                /* V36 */
  1516.   "Release 2.04",               /* V37 */
  1517.   "Release 2.1",                /* V38 */
  1518.   "Release 3.0",                /* V39 */
  1519.   "Release 3.1",                /* V40 */
  1520.   "Transitional Release 3.2",   /* V41 */
  1521.   "Transitional Release 3.3",   /* V42 */
  1522.   "Transitional Release 3.4",   /* V43 */
  1523.   "Release 3.5",                /* V44 */
  1524.   "Release 3.9",                /* V45 */
  1525. };
  1526.  
  1527. /* Keywords, which cannot be argument names. They are used case_insensitive to
  1528.    be sure they make no conflicts in non-C-languages as well.
  1529.    Currently these are mostly C keywords.
  1530. */
  1531. static const strptr Keywords[] =
  1532. {
  1533.   "and",        "and_eq",       "asm",          "auto",         "bitand",
  1534.   "bitor",      "break",        "case",         "catch",        "char",
  1535.   "class",      "compl",        "const",        "continue",     "default",
  1536.   "delete",     "do",           "double",       "else",         "enum",
  1537.   "extern",     "false",        "float",        "for",          "friend",
  1538.   "goto",       "if",           "inline",       "int",          "long",
  1539.   "new",        "not",          "not_eq",       "operator",     "or",
  1540.   "or_eq",      "private",      "protected",    "public",       "register",
  1541.   "return",     "short",        "signed",       "sizeof",       "static",
  1542.   "struct",     "switch",       "template",     "this",         "throw",
  1543.   "true",       "try",          "typedef",      "union",        "unsigned",
  1544.   "virtual",    "void",         "volatile",     "wchar_t",      "while",
  1545.   "xor",        "xor_eq",    "RastPort",    "Tag",
  1546.   0
  1547. };
  1548.  
  1549. #ifndef __SASC
  1550. static int stricmp(const char *a, const char *b)
  1551. {
  1552.   while(*a && tolower(*a) == tolower(*b))
  1553.   {
  1554.     ++a; ++b;
  1555.   }
  1556.   return (tolower(*a) - tolower(*b));
  1557. }
  1558.  
  1559. static int strnicmp(const char *a, const char *b, size_t num)
  1560. {
  1561.   while(num && *a && tolower(*a) == tolower(*b))
  1562.   {
  1563.     ++a; ++b; --num;
  1564.   }
  1565.   return num ? (tolower(*a) - tolower(*b)) : 0;
  1566. }
  1567. #endif
  1568.  
  1569. static strptr DupString(strptr Str, size_t Len)
  1570. {
  1571.   strptr res, r;
  1572.   if((res = r = AllocListMem(Len+1)))
  1573.   {
  1574.     while(Len-- && *Str)
  1575.       *(r++) = *(Str++);
  1576.     *r = '\0';
  1577.   }
  1578. #ifdef DEBUG_OLD
  1579.   printf("DupString %s.\n", res);
  1580. #endif
  1581.   return res;
  1582. }
  1583.  
  1584. static strptr AllocListMem(size_t size)
  1585. {
  1586.   strptr a;
  1587. #ifdef DEBUG_OLD
  1588.   printf("AllocListMem Size %ld.\n", size);
  1589. #endif
  1590.   if((a = (strptr) malloc(size)))
  1591.     memset(a, 0, size);
  1592.   return a;
  1593. }
  1594.  
  1595. static strptr SkipBlanks(strptr OldPtr)
  1596. {
  1597.   while(*OldPtr == ' ' || *OldPtr == '\t')
  1598.     ++OldPtr;
  1599.   return OldPtr;
  1600. }
  1601.  
  1602. static strptr SkipBlanksRet(strptr OldPtr)
  1603. {
  1604.   while(*OldPtr == ' ' || *OldPtr == '\t' || *OldPtr == '\n')
  1605.     ++OldPtr;
  1606.   return OldPtr;
  1607. }
  1608.  
  1609. /*
  1610.   This function is used to skip over variable names.
  1611.  
  1612.   Inputs: OldPtr  - pointer to the beginning of a string.
  1613.  
  1614.   Result: Pointer to the first character of the string, that is not one
  1615.     of a-z, A-Z, 0-9 or the underscore.
  1616. */
  1617.  
  1618. static strptr SkipName(strptr OldPtr)
  1619. {
  1620.   while(isalnum(*OldPtr) || *OldPtr == '_')
  1621.     ++OldPtr;
  1622.   return OldPtr;
  1623. }
  1624.  
  1625. static uint32 GetTypes(void)
  1626. {
  1627.   strptr ptr;
  1628.   size_t len;
  1629.   uint32 i;
  1630.  
  1631.   if(!(ptr = mygetfile(EXTTYPESFILE, &len)))
  1632.   {
  1633. #ifdef EXTTYPESFILEHIDDEN
  1634.     if((ptr = getenv("HOME")))
  1635.     {
  1636.       strptr ptrh = EXTTYPESFILEHIDDEN;
  1637.  
  1638.       i = strlen(ptr);
  1639.       ptr = DupString(ptr, i + sizeof(EXTTYPESFILEHIDDEN) + 1);
  1640.       if(i && ptr[i-1] != '/')
  1641.         ptr[i++] = '/';
  1642.       while(*ptrh)
  1643.         ptr[i++] = *(ptrh++);
  1644.       ptr[i] = 0;
  1645.       ptr = mygetfile(ptr, &len);
  1646.     }
  1647.     if(!ptr) /* disabled following if ptr != 0 */
  1648. #endif
  1649.     if(!(ptr = mygetfile(EXTTYPESFILE2, &len)))
  1650.     {
  1651.       DoError(ERR_NOFD2PRAGMATYPES, 0);
  1652.       ptr = (strptr) InternalTypes;
  1653.       len = sizeof(InternalTypes)-1;
  1654.     }
  1655.   }
  1656.   if((i = ScanTypes(ptr, len)) > 0)
  1657.   {
  1658.     DoError(ERR_WRONG_TYPES_LINE, i);
  1659.     return 0;
  1660.   }
  1661.   return 1;
  1662. }
  1663.  
  1664. static strptr GetBaseType(void)
  1665. {
  1666.   static strptr basetype = 0;
  1667.   uint32 i;
  1668.  
  1669.   if(Flags2 & FLAG2_VOIDBASE)
  1670.     basetype = "void *";
  1671.   else if(!basetype)
  1672.   {
  1673.     for(i = 0; !libtype && BaseName && Proto_LibTypes[i].BaseName; ++i)
  1674.     {
  1675.       if(Proto_LibTypes[i].StructureName && !(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
  1676.       {
  1677.         libtype = Proto_LibTypes[i].StructureName;
  1678.       }
  1679.     }
  1680.     if(libtype && (basetype = malloc(strlen(libtype) + 9+1)))
  1681.     {
  1682.       sprintf(basetype, "struct %s *", libtype);
  1683.     }
  1684.     if(!libtype)
  1685.       basetype = "struct Library *";
  1686.   }
  1687.  
  1688.   return basetype;
  1689. }
  1690.  
  1691. static strptr GetBaseTypeLib(void)
  1692. {
  1693.   uint32 i;
  1694.  
  1695.   if(libtype)
  1696.     return libtype;
  1697.  
  1698.   for(i = 0; BaseName && Proto_LibTypes[i].BaseName; ++i)
  1699.   {
  1700.     if(Proto_LibTypes[i].StructureName && !(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
  1701.     {
  1702.       return Proto_LibTypes[i].StructureName;
  1703.     }
  1704.   }
  1705.   return "Library";
  1706. }
  1707.  
  1708. static strptr GetLibraryName(void)
  1709. {
  1710.   uint32 i;
  1711.  
  1712.   if(libname)
  1713.     return libname;
  1714.  
  1715.   for(i = 0; BaseName && Proto_LibTypes[i].BaseName; ++i)
  1716.   {
  1717.     if(Proto_LibTypes[i].LibraryName && !(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
  1718.     {
  1719.       return (libname = Proto_LibTypes[i].LibraryName);
  1720.     }
  1721.   }
  1722.   if(!(libname = malloc(strlen(ShortBaseName)+9)))
  1723.     return 0;
  1724.  
  1725.   /* auto create name */
  1726.   for(i = 0; ShortBaseName[i]; ++i)
  1727.     libname[i] = ShortBaseName[i];
  1728.   strcpy(libname+i,".library");
  1729.   return libname;
  1730. }
  1731.  
  1732. static int32 MakeShortBaseName(void)
  1733. {
  1734.   strptr ptr, p2;
  1735.   uint32 i;
  1736.  
  1737.   ptr = p2 = args.infile;
  1738.   while(*p2)
  1739.   {
  1740.     if(*p2 == '/' || *p2 == ':' || *p2 == '\\')
  1741.       ptr = p2+1;
  1742.     ++p2;
  1743.   }
  1744.  
  1745.   /* first get name from file */
  1746.  
  1747.   p2 -= (sizeof(SFDFILEEXTENSION)-1);
  1748.   if(p2 > ptr && !stricmp(p2, SFDFILEEXTENSION))
  1749.     ShortBaseName = DupString(ptr, p2-ptr);
  1750.   p2 += sizeof(SFDFILEEXTENSION)-sizeof(FDFILEEXTENSION);
  1751.   if(p2 > ptr && !stricmp(p2, FDFILEEXTENSION))
  1752.     ShortBaseName = DupString(ptr, p2-ptr);
  1753.  
  1754.   /* then try exceptions (overriding filename) */
  1755.   if(BaseName)
  1756.   {
  1757.     for(i = 0; BaseName && Proto_LibTypes[i].BaseName; ++i)
  1758.     {
  1759.       if(Proto_LibTypes[i].ShortBaseName && !(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
  1760.       {
  1761.         if(!(ShortBaseName = DupString(Proto_LibTypes[i].ShortBaseName,
  1762.         strlen(Proto_LibTypes[i].ShortBaseName))))
  1763.           return 0;
  1764.         break;
  1765.       }
  1766.     }
  1767.     /* and last use default method */
  1768.     if(!ShortBaseName)
  1769.       ShortBaseName = DupString(BaseName, strlen(BaseName)-4);
  1770.   }
  1771.  
  1772.   if(!ShortBaseName)
  1773.     return 0;
  1774.  
  1775.   ptr = ShortBaseName;
  1776.   while((*ptr = tolower(*ptr))) /* Convert to lowercase */
  1777.     ptr++;
  1778.   
  1779.   if((ShortBaseNameUpper = DupString(ShortBaseName, strlen(ShortBaseName))))
  1780.   {
  1781.     ptr = ShortBaseNameUpper;
  1782.     while((*ptr = toupper(*ptr))) /* Convert to uppercase */
  1783.       ptr++;
  1784.   }
  1785.   else
  1786.     return 0;
  1787.  
  1788.   return 1;
  1789. }
  1790.  
  1791. static uint32 OpenDest(strptr name)
  1792. {
  1793.   static uint8 printedname = 0;
  1794.   strptr b, t;
  1795.  
  1796.   t = (strptr) tempbuf;
  1797.   if((b = args.to) && *b)
  1798.   {
  1799.     while(*b)
  1800.       *(t++) = *(b++);
  1801.     if(*(t-1) != ':' && *(t-1) != '/')
  1802.       *(t++) = '/';
  1803.   }
  1804.   *t = 0;
  1805.  
  1806.   if(!(Flags & FLAG_SINGLEFILE))
  1807.     printf("ResultFile: %s%s\n", tempbuf, name);
  1808.   else if(!printedname++)
  1809.   {
  1810.     printf("ResultType: %s", tempbuf); printf(filenamefmt, "*");
  1811.     printf("\n");
  1812.   }
  1813.  
  1814.   while(*name)
  1815.     *(t++) = *(name++);
  1816.   *t = 0;
  1817.  
  1818.   if(args.header)
  1819.   {
  1820.     HEADER = mygetfile((strptr)tempbuf, &headersize);
  1821.     FindHeader();
  1822.   }
  1823.  
  1824.   if((outfile = fopen((strptr)tempbuf, "wb")))
  1825.     return 1;
  1826.   DoError(ERR_OPEN_FILE, 0, tempbuf);
  1827.   return 0;
  1828. }
  1829.  
  1830. static uint32 CloseDest(strptr name)
  1831. {
  1832.   if(outfile)
  1833.   {
  1834.     fclose(outfile);
  1835.     outfile = 0;
  1836.  
  1837.     if(!(Flags & FLAG_DONE) || !Output_Error)
  1838.     {
  1839.       strptr b, t;
  1840.       if(!Output_Error || !(Flags & FLAG_SINGLEFILE))
  1841.         DoError(ERR_EMPTY_FILE, 0);
  1842.  
  1843.       t = (strptr) tempbuf;
  1844.       if((b = args.to) && *b)
  1845.       {
  1846.         while(*b)
  1847.           *(t++) = *(b++);
  1848.         if(*(t-1) != ':' && *(t-1) != '/')
  1849.           *(t++) = '/';
  1850.       }
  1851.       while(*name)
  1852.         *(t++) = *(name++);
  1853.       *t = 0;
  1854.  
  1855.       remove((strptr)tempbuf);
  1856.       return 0;
  1857.     }
  1858.     Flags &= ~FLAG_DONE;        /* clear the flag */
  1859.   }
  1860.   else
  1861.     return 0;
  1862.   return 1;
  1863. }
  1864.  
  1865. static uint32 MakeTagFunction(struct AmiPragma *ap)
  1866. {
  1867.   size_t len = strlen(ap->FuncName);
  1868.   long i=0;
  1869.  
  1870. #ifdef DEBUG_OLD
  1871.   printf("MakeTagFunction:\n");
  1872. #endif
  1873.  
  1874.   if(!ap->NumArgs || ap->TagName)
  1875.     return 1;
  1876.  
  1877.   ++tagfuncs;
  1878.   ap->Flags |= AMIPRAGFLAG_OWNTAGFUNC;
  1879.  
  1880.   while(Pragma_ExecpNames[i].FunctionName && /* check the exception names */
  1881.   strcmp(ap->FuncName, Pragma_ExecpNames[i].FunctionName))
  1882.     ++i;
  1883.  
  1884.   if(Pragma_ExecpNames[i].FunctionName)
  1885.   {
  1886.     if(!(ap->TagName = Pragma_ExecpNames[i].TagName))
  1887.     {
  1888.       ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC;
  1889.       --tagfuncs;
  1890.     }
  1891.   }
  1892.   else if(ap->FuncName[len-1] == 'A')
  1893.   {
  1894.     if(!strcmp(ap->FuncName+len-3, "DMA") ||
  1895.     !strcmp(ap->FuncName+len-4, "MESA")) /* skip names with DMA or MESA at end */
  1896.     { ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC; --tagfuncs; return 1;}
  1897.     if(!(ap->TagName = DupString(ap->FuncName, len-1)))
  1898.       return 0;
  1899.   }
  1900.   else if(!strcmp(ap->FuncName + len-7, "TagList"))
  1901.   {
  1902.     if(!(ap->TagName = DupString(ap->FuncName, len-3)))
  1903.       return 0;
  1904.     ap->TagName[len-4] = 's';
  1905.   }
  1906.   else if(!strcmp(ap->FuncName + len-4, "Args"))
  1907.   {
  1908.     if(!(ap->TagName = DupString(ap->FuncName, len-4)))
  1909.       return 0;
  1910.   }
  1911.   else if(!stricmp(ap->Args[ap->CallArgs-1].ArgName, "tags") ||
  1912.   !stricmp(ap->Args[ap->CallArgs-1].ArgName, "taglist"))
  1913.   {
  1914.     if(!(ap->TagName = DupString(ap->FuncName, len+4)))
  1915.       return 0;
  1916.     memcpy(ap->TagName + len, "Tags", 5);
  1917.   }
  1918.   else if(!stricmp(ap->Args[ap->CallArgs-1].ArgName, "args"))
  1919.   {
  1920.     if(!(ap->TagName = DupString(ap->FuncName, len+4)))
  1921.       return 0;
  1922.     memcpy(ap->TagName + len, "Args", 5);
  1923.   }
  1924.   else
  1925.   {
  1926.     ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC;
  1927.     --tagfuncs; /* not a tagfunction, incrementing was false, undo it */
  1928.   }
  1929.  
  1930.   return 1;
  1931. }
  1932.  
  1933. static void MakeLines(strptr buffer, uint32 size)
  1934. {
  1935.   if(size && buffer)
  1936.   {
  1937.     /* make a real C++ zero string ending line */
  1938.     while(size--)
  1939.     {
  1940.       if(*buffer == '\n')
  1941.         *buffer = '\0';
  1942.       ++buffer;
  1943.     }
  1944.     *buffer = '\0';
  1945.   }
  1946. }
  1947.  
  1948. /* Do any special functions, which cannot be done with other exception
  1949.    stuff - currently only dos.library DoPkt function. */
  1950. static uint32 SpecialFuncs(void)
  1951. {
  1952.   struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.Last, *ap2 = (struct AmiPragma *) AmiPragma.First;
  1953.  
  1954.   /* first let one more go away, so we can detect if the DoPkt parts are
  1955.      already inserted in the FD file */
  1956.  
  1957.   while(ap2 && (struct AmiPragma *)(ap2->List.Next) != ap)
  1958.     ap2 = (struct AmiPragma *)(ap2->List.Next);
  1959.  
  1960.   if(ap2 && ap2->Bias == 0xF0 && ap->Bias != 0xF0 && !strcmp("DoPkt", ap2->FuncName))
  1961.   {
  1962.     struct AmiPragma *d;
  1963.     uint32 i;
  1964.  
  1965.     RemoveItem(&AmiPragma, (struct ShortList *) ap); /* add in correct order */
  1966.     for(i = 0; i < 5; ++i)
  1967.     {
  1968.       if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
  1969.         return 0;
  1970.       memcpy(d, ap2, sizeof(struct AmiPragma));
  1971.       d->FuncName = DupString(ap2->FuncName, 6);
  1972.       d->FuncName[5] = '0'+i;
  1973.       d->NumArgs = d->CallArgs = i + 2;
  1974.       AddItem(&AmiPragma, (struct ShortList *) d);
  1975.     }
  1976.     AddItem(&AmiPragma, (struct ShortList *) ap);
  1977.   }
  1978.   return 1;
  1979. }
  1980.  
  1981. static void SortFDList(void)
  1982. {
  1983.   struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.First, *ap2, *ap3;
  1984.   AmiPragma.First = AmiPragma.Last = 0;
  1985.  
  1986.   while(ap)
  1987.   {
  1988.     ap3 = 0;
  1989.     ap2 = (struct AmiPragma *) AmiPragma.First;
  1990.  
  1991.     /* for FD2Inline style we need to use strcmp instead of stricmp here */
  1992.     while(ap2 && stricmp(ap2->FuncName, ap->FuncName) < 0)
  1993.     {
  1994.       ap3 = ap2;
  1995.       ap2 = (struct AmiPragma *) ap2->List.Next;
  1996.     }
  1997.  
  1998.     ap2 = ap;
  1999.     ap = (struct AmiPragma *) ap->List.Next;
  2000.  
  2001.     if(ap3)
  2002.     {
  2003.       ap2->List.Next = (struct ShortList *) ap3->List.Next;
  2004.       ap3->List.Next = (struct ShortList *) ap2;
  2005.     }
  2006.     else
  2007.     {
  2008.       ap2->List.Next = AmiPragma.First;
  2009.       AmiPragma.First = (struct ShortList *) ap2;
  2010.     }
  2011.     if(ap && !ap->List.Next)
  2012.       AmiPragma.Last = (struct ShortList *) ap2;
  2013.   }
  2014. }
  2015.  
  2016. static void AddAliasName(struct AmiPragma *ap, struct Pragma_AliasName *alias, uint32 linenum)
  2017. {
  2018.   uint32 i;
  2019.  
  2020.   if(ap->NumAlias > NUMALIASNAMES)
  2021.     DoError(ERR_ALIASNAMES, linenum, NUMALIASNAMES);
  2022.   else
  2023.   {
  2024.     /* prevent double names */
  2025.     for(i = 0; i < ap->NumAlias; ++i)
  2026.     {
  2027.       if(!strcmp(ap->AliasName[i]->AliasName, alias->AliasName))
  2028.         return;
  2029.     }
  2030.     ap->AliasName[ap->NumAlias++] = alias;
  2031.   }
  2032. }
  2033.  
  2034. static uint32 CheckNames(struct AmiPragma *ap)
  2035. {
  2036.   uint32 i, j;
  2037.   const strptr *k;
  2038.  
  2039. #ifdef DEBUG_OLD
  2040.   printf("CheckNames\n");
  2041. #endif
  2042.   for(i = 0; i < ap->CallArgs; ++i)
  2043.   {
  2044.     if(!ap->Args[i].ArgName)
  2045.     {
  2046.       if(!(ap->Args[i].ArgName = (strptr) AllocListMem(4+strlen(RegNames[ap->Args[i].ArgReg]))))
  2047.         return 0;
  2048.       sprintf(ap->Args[i].ArgName, "%sarg", RegNames[ap->Args[i].ArgReg]);
  2049.     }
  2050.     else
  2051.     {
  2052.       for(k = Keywords; *k; ++k)
  2053.       {
  2054.         if(!stricmp(ap->Args[i].ArgName, *k))
  2055.         {
  2056.           DoError(ERR_ARGNAME_KEYWORD_CONFLICT, ap->Line, i, *k);
  2057.           if(!(ap->Args[i].ArgName = (strptr) AllocListMem(4+strlen(RegNames[ap->Args[i].ArgReg]))))
  2058.             return 0;
  2059.           sprintf(ap->Args[i].ArgName, "%sarg", RegNames[ap->Args[i].ArgReg]);
  2060.         }
  2061.       }
  2062.       for(j = 0; j < i; ++j)
  2063.       {
  2064.         if(!stricmp(ap->Args[i].ArgName, ap->Args[j].ArgName))
  2065.         {
  2066.           DoError(ERR_ARGNAME_ARGNAME_CONFLICT, ap->Line, i+1, j+1);
  2067.           if(!(ap->Args[i].ArgName = (strptr) AllocListMem(4+strlen(RegNames[ap->Args[i].ArgReg]))))
  2068.             return 0;
  2069.           sprintf(ap->Args[i].ArgName, "%sarg", RegNames[ap->Args[i].ArgReg]);
  2070.         }
  2071.       }
  2072.     }
  2073.   }
  2074.   /* NOTE: the replaced argument names aren't checked for conflicts */
  2075.   /* replaced names are of style a0arg */
  2076.   return 1;
  2077. }
  2078.  
  2079. static uint32 ScanSFDFile(uint32 abi)
  2080. {
  2081.   uint32 _public = 1;
  2082.   int32 bias = -1;
  2083.   uint32 linenum;
  2084.   uint32 actcom = 0;
  2085.   uint32 functype = 0;
  2086.  
  2087.   Flags2 |= FLAG2_SFDMODE;
  2088.  
  2089.   if(strncmp("==id", in.pos, 4))
  2090.     DoError(ERR_SFD_START, 1);
  2091.  
  2092.   for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
  2093.   {
  2094.     if(*in.pos == '*')
  2095.     {
  2096.       if(actcom)
  2097.         *(in.pos-1) = '\n';
  2098.       else
  2099.       {
  2100.         struct Comment *d;
  2101.         if(!(d = (struct Comment *) NewItem(&Comment)))
  2102.           return 0;
  2103.         d->Bias = bias;
  2104.         d->Data = in.pos;
  2105.         d->ReservedNum = 0;
  2106.         d->Version = 0;
  2107.         d->Private = _public ? 0 : 1;
  2108.         AddItem(&Comment, (struct ShortList *) d);
  2109.         actcom = 1;
  2110.       }
  2111.       while(*in.pos)
  2112.         ++in.pos;
  2113.     }
  2114.     else if(*in.pos == '=' && in.pos[1] == '=')
  2115.     {
  2116.       in.pos += 2;
  2117.       actcom = 0; /* no Comment */
  2118.  
  2119.       if(!strnicmp(in.pos, "basetype", 8))
  2120.       {
  2121. #ifdef DEBUG_OLD
  2122.   printf("ScanSFDFile: found ==basetype\n");
  2123. #endif
  2124.         if(!(Flags2 & FLAG2_LIBTYPE))
  2125.         {
  2126.           if(libtype)
  2127.             DoError(ERR_LIBTYPE_DECLARED_TWICE, linenum);
  2128.  
  2129.           in.pos = SkipBlanks(in.pos+8);
  2130.           if(strncmp(in.pos, "struct", 6))
  2131.             DoError(ERR_EXPECTED_STRUCT, linenum);
  2132.           else
  2133.           {
  2134.             in.pos = SkipBlanks(in.pos+6);
  2135.             if(!*in.pos)
  2136.               DoError(ERR_EXPECTED_LIBTYPE, linenum);
  2137.             else
  2138.             {
  2139.               libtype = in.pos;
  2140.               in.pos = SkipName(libtype);
  2141.               if(*SkipBlanks(in.pos) != '*')
  2142.                 DoError(ERR_EXPECTED_POINTERSIGN, linenum);
  2143.               if(*in.pos)
  2144.                 *(in.pos++) = 0;
  2145.             }
  2146.           }
  2147.         }
  2148.         else
  2149.           DoError(ERR_COMMANDLINE_LIBTYPE, linenum);
  2150.         while(*in.pos)
  2151.           ++in.pos;
  2152.       }
  2153.       else if(!strnicmp(in.pos, "copyright", 9))
  2154.       {
  2155.         Copyright = SkipBlanks(in.pos+9);
  2156.         while(*in.pos)
  2157.           ++in.pos;
  2158.       }
  2159.       else if(!strnicmp(in.pos, "libname", 7))
  2160.       {
  2161. #ifdef DEBUG_OLD
  2162.   printf("ScanSFDFile: found ==libname\n");
  2163. #endif
  2164.         if(!(Flags2 & FLAG2_LIBNAME))
  2165.         {
  2166.           if(libname)
  2167.             DoError(ERR_LIBNAME_DECLARED_TWICE, linenum);
  2168.  
  2169.           in.pos = SkipBlanks(in.pos+7);
  2170.           if(!*in.pos)
  2171.             DoError(ERR_EXPECTED_LIBNAME, linenum);
  2172.           else
  2173.             in.pos = SkipName(libname = in.pos);
  2174.         }
  2175.         else
  2176.           DoError(ERR_COMMANDLINE_LIBNAME, linenum);
  2177.         while(*in.pos)
  2178.           ++in.pos;
  2179.       }
  2180.       else if(!strnicmp(in.pos, "base", 4))
  2181.       {
  2182.         strptr oldptr;
  2183.  
  2184. #ifdef DEBUG_OLD
  2185.   printf("ScanSFDFile: found ==base\n");
  2186. #endif
  2187.         if(!(Flags & FLAG_BASENAME))
  2188.         {
  2189.           if(BaseName)
  2190.             DoError(ERR_BASENAME_DECLARED_TWICE, linenum);
  2191.  
  2192.           in.pos = SkipBlanks(in.pos+4);
  2193.           if(*in.pos != '_')
  2194.             DoError(ERR_EXPECTED_SLASH_IN_BASENAME, linenum);
  2195.           else
  2196.             ++in.pos;
  2197.  
  2198.           BaseName = oldptr = in.pos;
  2199.           in.pos = SkipName(in.pos);
  2200.           if(!(in.pos-oldptr))
  2201.             DoError(ERR_EXPECTED_BASENAME, linenum);
  2202.         }
  2203.         else
  2204.         {
  2205.           DoError(ERR_COMMANDLINE_BASENAME, linenum);
  2206.           while(*in.pos)
  2207.             ++in.pos;
  2208.         }
  2209.       }
  2210.       else if(!strnicmp(in.pos, "bias", 4))
  2211.       {
  2212.         strptr ptr;
  2213.         int32 newbias;
  2214.  
  2215. #ifdef DEBUG_OLD
  2216.   printf("ScanSFDFile: found ==bias\n");
  2217. #endif
  2218.         in.pos += 5;
  2219.         newbias = strtol(in.pos, &ptr, 10);
  2220.         if(ptr == in.pos)
  2221.           DoError(ERR_EXPECTED_BIAS_VALUE, linenum);
  2222.         else if(newbias < 0)
  2223.         {
  2224.           DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE, linenum);
  2225.           bias = -newbias;
  2226.         }
  2227.         else
  2228.           bias = newbias;
  2229.         in.pos = SkipName(in.pos);
  2230.       }
  2231.       else if(!strnicmp(in.pos, "end", 3))
  2232.       {
  2233.         bias = 0; break;
  2234.       }
  2235.       else if(!strnicmp(in.pos, "public", 6))
  2236.       {
  2237.         in.pos += 6;
  2238.         _public = 1;
  2239.       }
  2240.       else if(!strnicmp(in.pos, "private", 7))
  2241.       {
  2242.         in.pos += 7;
  2243.         _public = 0;
  2244.       }
  2245.       else if(!strnicmp(in.pos, "abi", 3))
  2246.       {
  2247. #ifdef DEBUG_OLD
  2248.   printf("ScanSFDFile: found ==abi\n");
  2249. #endif
  2250.         in.pos = SkipBlanks(in.pos+3);
  2251.         if(!strnicmp(in.pos, "M68k", 4))
  2252.         {
  2253.           abi = ABI_M68K; in.pos += 4;
  2254.         }
  2255.         else if(!strnicmp(in.pos, "PPC0", 4))
  2256.         {
  2257.           abi = ABI_PPC0; in.pos += 4;
  2258.         }
  2259.         else if(!strnicmp(in.pos, "PPC2", 4))
  2260.         {
  2261.           abi = ABI_PPC2; in.pos += 4;
  2262.         }
  2263.         else if(!strnicmp(in.pos, "PPC", 3))
  2264.         {
  2265.           abi = ABI_PPC; in.pos += 3;
  2266.         }
  2267.         else
  2268.           DoError(ERR_UNKNOWN_ABI, linenum, in.pos);
  2269.       }
  2270.       else if(!strnicmp(in.pos, "id", 2))
  2271.       {
  2272.         if(IDstring)
  2273.           DoError(ERR_IDSTRING_DECLARED_TWICE, linenum);
  2274.         IDstring = in.pos = SkipBlanks(in.pos+2);
  2275.         if(strncmp(in.pos, "$Id: ", 5))
  2276.         {
  2277.           DoError(ERR_EXCPECTED_IDSTRING, linenum);
  2278.         }
  2279.         while(*in.pos)
  2280.           ++in.pos;
  2281.         if(*(in.pos-1) != '$')
  2282.           DoError(ERR_EXPECTED_ID_ENDSIGN, linenum);
  2283.       }
  2284.       else if(!strnicmp(in.pos, "include", 7))
  2285.       {
  2286.         struct Include *d;
  2287.  
  2288.         if(!(d = (struct Include *) NewItem(&Includes)))
  2289.           return 0;
  2290.         d->Include = SkipBlanks(in.pos+7);
  2291.         AddItem(&Includes, (struct ShortList *) d);
  2292.         while(*in.pos)
  2293.           ++in.pos;
  2294.       }
  2295.       else if(!strnicmp(in.pos, "varargs", 7))
  2296.       {
  2297.         if(bias == -1)
  2298.           DoError(ERR_VARARGS_ALIAS_FIRST, linenum);
  2299.         else
  2300.         {
  2301.           if(!functype)
  2302.             bias -= BIAS_OFFSET;
  2303.           functype |= FUNCFLAG_TAG;
  2304.         }
  2305.         in.pos += 7;
  2306.       }
  2307.       else if(!strnicmp(in.pos, "alias", 5))
  2308.       {
  2309.         if(bias == -1)
  2310.           DoError(ERR_VARARGS_ALIAS_FIRST, linenum);
  2311.         else
  2312.         {
  2313.           if(!functype)
  2314.             bias -= BIAS_OFFSET;
  2315.           functype |= FUNCFLAG_ALIAS;
  2316.         }
  2317.         in.pos += 5;
  2318.       }
  2319.       else if(!strnicmp(in.pos, "version", 7))
  2320.       {
  2321.         /* store version entries as comments */
  2322.         struct Comment *d;
  2323.         strptr ptr;
  2324.         int16 v;
  2325.  
  2326.         in.pos = SkipBlanks(in.pos+7);
  2327.         v = strtol(in.pos, &ptr, 10);
  2328. #ifdef DEBUG_OLD
  2329.   printf("ScanSFDFile: found ==version %d\n", v);
  2330. #endif
  2331.         if(ptr == in.pos || v < 0)
  2332.           DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER, linenum);
  2333.         else
  2334.         {
  2335.           if(!(d = (struct Comment *) NewItem(&Comment)))
  2336.             return 0;
  2337.           d->Bias = bias;
  2338.           d->Data = 0;
  2339.           d->ReservedNum = 0;
  2340.           d->Version = v;
  2341.           d->Private = _public ? 0 : 1;
  2342.           AddItem(&Comment, (struct ShortList *) d);
  2343.           in.pos = SkipName(in.pos);
  2344.         }
  2345.       }
  2346.       else if(!strnicmp(in.pos, "reserve", 7))
  2347.       {
  2348.         /* store reserved entries as comments */
  2349.         struct Comment *d;
  2350.         strptr ptr;
  2351.         int16 v;
  2352.  
  2353.         in.pos = SkipBlanks(in.pos+7);
  2354.         v = strtol(in.pos, &ptr, 10);
  2355. #ifdef DEBUG_OLD
  2356.   printf("ScanSFDFile: found ==reserve %d\n", v);
  2357. #endif
  2358.         if(bias == -1)
  2359.         {
  2360.           DoError(ERR_ASSUMING_BIAS_OF_30, linenum);
  2361.           bias = BIAS_START;
  2362.         }
  2363.  
  2364.         if(ptr == in.pos || v < 0)
  2365.           DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER, linenum);
  2366.         else
  2367.         {
  2368.           if(!(d = (struct Comment *) NewItem(&Comment)))
  2369.             return 0;
  2370.           d->Bias = bias;
  2371.           d->Data = 0;
  2372.           d->ReservedNum = v;
  2373.           d->Version = 0;
  2374.           d->Private = _public ? 0 : 1;
  2375.           AddItem(&Comment, (struct ShortList *) d);
  2376.           in.pos = SkipName(in.pos);
  2377.           bias += BIAS_OFFSET*v;
  2378.         }
  2379.       }
  2380.       else
  2381.         DoError(ERR_UNKNOWN_DIRECTIVE, linenum, in.pos-2);
  2382.     }
  2383.     else /* function */
  2384.     {
  2385.       uint32 ft, startlinenum;
  2386.       struct AmiPragma ap, *ap2;
  2387.       struct ClibData d, *f;
  2388.       strptr oldptr;
  2389.       uint32 maxreg;
  2390.       strptr data;
  2391.  
  2392.       actcom = 0;
  2393.       maxreg = ((abi == ABI_M68K) ? MAXREG-2 : MAXREGPPC);
  2394.       /* join lines, if necessary */
  2395.       startlinenum = linenum;
  2396.       data = in.pos;
  2397.       while(*data != '('/*)*/ && data < in.buf + in.size) /* first open bracket */
  2398.       { if(!*data) {*data = ' '; ++linenum; } ++data; }
  2399.       ++data;
  2400.       ft = 0; /* this is needed for function pointer types, which have own brackets */
  2401.       while((*data != /*(*/')' || ft) && data < in.buf + in.size) /* first close bracket */
  2402.       {
  2403.         if(!*data)
  2404.         {
  2405.           *data = ' ';
  2406.           ++linenum;
  2407.         }
  2408.         else if(*data == '('/*)*/)
  2409.           ++ft;
  2410.         else if(*data == /*(*/')')
  2411.           --ft;
  2412.         ++data;
  2413.       }
  2414.       while(*data != '('/*)*/ && data < in.buf + in.size) /* second open bracket */
  2415.       { if(!*data) {*data = ' '; ++linenum; } ++data; }
  2416.       while(*data != /*(*/')' && data < in.buf + in.size) /* second close bracket */
  2417.       { if(!*data) {*data = ' '; ++linenum; } ++data; }
  2418.       if(data == in.buf + in.size)
  2419.       {
  2420.         in.pos = data;
  2421.         DoError(ERR_UNEXPECTED_FILEEND, linenum);
  2422.         continue;
  2423.       }
  2424.  
  2425.       ft = functype; functype = 0;
  2426.       memset(&ap, 0, sizeof(struct AmiPragma));
  2427.       memset(&d, 0, sizeof(struct ClibData));
  2428.       if(!GetCPPType(&d.ReturnType, in.pos, 1, 1))
  2429.       {
  2430.         DoError(ERR_UNKNOWN_RETURNVALUE_TYPE, startlinenum);
  2431.         while(*(in.pos++))
  2432.           ;
  2433.         continue;
  2434.       }
  2435.       else if(d.ReturnType.Unknown)
  2436.         DoError(ERR_UNKNOWN_RETURNVALUE_TYPE_INT, startlinenum,
  2437.         d.ReturnType.Unknown);
  2438.  
  2439.       ap.FuncName = d.FuncName = SkipBlanks(d.ReturnType.TypeStart+d.ReturnType.FullLength);
  2440.       in.pos = SkipBlanks(SkipName(d.FuncName));
  2441.         ;
  2442.       if(*in.pos != '('/*)*/)
  2443.       {
  2444.         DoError(ERR_EXPECTED_OPEN_BRACKET, startlinenum);
  2445.         ++in.pos;
  2446.         continue;
  2447.       }
  2448.       *(SkipName(d.FuncName)) = 0;
  2449.       in.pos = SkipBlanks(++in.pos);
  2450.  
  2451.       oldptr = 0;
  2452.       while(*in.pos && *in.pos != /*(*/')')
  2453.       {
  2454.         oldptr = (strptr) 1;
  2455.         if(d.NumArgs >= maxreg)
  2456.         {
  2457.           DoError(ERR_TO_MUCH_ARGUMENTS, startlinenum);
  2458.           return 0;
  2459.         }
  2460.         else if(!GetCPPType(&d.Args[d.NumArgs++], in.pos, 0, 0))
  2461.         {
  2462.           DoError(ERR_UNKNOWN_VARIABLE_TYPE, startlinenum, d.NumArgs);
  2463.           break;
  2464.         }
  2465.         else if(d.Args[d.NumArgs-1].Unknown)
  2466.           DoError(ERR_UNKNOWN_VARIABLE_TYPE_INT, startlinenum, d.NumArgs,
  2467.           d.Args[d.NumArgs-1].Unknown);
  2468.  
  2469.         oldptr = in.pos = SkipBlanks(d.Args[d.NumArgs-1].TypeStart + d.Args[d.NumArgs-1].FullLength);
  2470.         if(d.Args[d.NumArgs-1].Type != CPP_TYPE_VARARGS)
  2471.         {
  2472.           if(d.Args[d.NumArgs-1].Flags & CPP_FLAG_FUNCTION)
  2473.           {
  2474.             oldptr = d.Args[d.NumArgs-1].FunctionName;
  2475.             if(!oldptr)
  2476.             {
  2477.               DoError(ERR_EXPECTED_ARGUMENT_NAME, startlinenum);
  2478.               break;
  2479.             }
  2480.             else if(!(oldptr = DupString(oldptr, SkipName(oldptr)-oldptr)))
  2481.               return 0;
  2482.             ap.Args[ap.CallArgs++].ArgName = oldptr;
  2483.           }
  2484.           else
  2485.           {
  2486.             ap.Args[ap.CallArgs++].ArgName = in.pos;
  2487.             in.pos = SkipName(in.pos);
  2488.  
  2489.             if(in.pos == oldptr)
  2490.             {
  2491.               DoError(ERR_EXPECTED_ARGUMENT_NAME, startlinenum);
  2492.               break;
  2493.             }
  2494.           }
  2495.         }
  2496.         else
  2497.           ++ap.CallArgs;
  2498.  
  2499.         in.pos = SkipBlanks(in.pos);
  2500.         if(*in.pos != ',' && *in.pos != /*(*/')')
  2501.         {
  2502.           DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
  2503.           break;
  2504.         }
  2505.         if(*in.pos == ')')
  2506.         {
  2507.           in.pos = SkipBlanks(++in.pos);
  2508.           if(d.Args[d.NumArgs-1].Type != CPP_TYPE_VARARGS && !(d.Args[d.NumArgs-1].Flags & CPP_FLAG_FUNCTION))
  2509.             *(SkipName(oldptr)) = 0;
  2510. #ifdef DEBUG_OLD
  2511.   printf("Added last argument %ld (%s) for %s (%ld bytes)\n", d.NumArgs, oldptr, d.FuncName,
  2512.   d.Args[d.NumArgs-1].FullLength);
  2513. #endif
  2514.           oldptr = 0;
  2515.           break;
  2516.         }
  2517.         else
  2518.         {
  2519.           in.pos = SkipBlanks(++in.pos);
  2520.           *(SkipName(oldptr)) = 0;
  2521. #ifdef DEBUG_OLD
  2522.   printf("Added argument %ld (%s) for %s (%ld bytes)\n", d.NumArgs, oldptr, d.FuncName,
  2523.   d.Args[d.NumArgs-1].FullLength);
  2524. #endif
  2525.         }
  2526.       }
  2527.       if(*in.pos == /*(*/')')
  2528.         ++in.pos;
  2529.       if(!oldptr) /* oldptr == 0 means parsing was valid */
  2530.       {
  2531.         if(!(f = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
  2532.           return -1;
  2533.  
  2534.         memcpy(f, &d, sizeof(struct ClibData));
  2535.  
  2536.         if(!clibdata)
  2537.           clibdata = f;
  2538.         else
  2539.         {
  2540.           struct ClibData *e = clibdata;
  2541.           while(e->Next)
  2542.             e = e->Next;
  2543.           e->Next = f;
  2544.         }
  2545.  
  2546. #ifdef DEBUG_OLD
  2547.   printf("Added prototype for %s (line %ld) with %ld args\n", f->FuncName, startlinenum, f->NumArgs);
  2548. #endif
  2549.         if(*(in.pos = SkipBlanks(in.pos)) != '('/*)*/)
  2550.         {
  2551.           DoError(ERR_EXPECTED_OPEN_BRACKET, startlinenum);
  2552.           ++in.pos;
  2553.           continue;
  2554.         }
  2555.  
  2556.         if(bias == -1)
  2557.         {
  2558.           DoError(ERR_ASSUMING_BIAS_OF_30, startlinenum);
  2559.           bias = BIAS_START;
  2560.         }
  2561.  
  2562.         ap.Bias = bias;
  2563.         ap.Abi = abi;
  2564.         ap.Line = startlinenum;
  2565.         bias += BIAS_OFFSET;
  2566.  
  2567.         if(_public)
  2568.           ap.Flags |= AMIPRAGFLAG_PUBLIC;
  2569.  
  2570.         if(abi != ABI_M68K)
  2571.         {
  2572.           while(*in.pos && *in.pos != /*(*/')')
  2573.            ++in.pos;
  2574.           if(*in.pos != /*(*/')')
  2575.           {
  2576.             DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
  2577.             ++in.pos;
  2578.             continue;
  2579.           }
  2580.           ++in.pos;
  2581.           ap.NumArgs = ap.CallArgs;
  2582.  
  2583.           ap.Flags |= AMIPRAGFLAG_PPC;
  2584.           if(abi == ABI_PPC0)
  2585.             ap.Flags |= AMIPRAGFLAG_PPC0;
  2586.           else if(abi == ABI_PPC2)
  2587.             ap.Flags |= AMIPRAGFLAG_PPC2;
  2588.         }
  2589.         else
  2590.         {
  2591.           uint32 len;
  2592.  
  2593.           do
  2594.           {
  2595.             uint32 i;
  2596.  
  2597.             oldptr = in.pos = SkipBlanks(in.pos+1);
  2598.  
  2599.             if(*in.pos == /*(*/')' && !ap.NumArgs)
  2600.               break;
  2601.  
  2602.             in.pos = SkipName(oldptr);
  2603.             len = in.pos-oldptr;
  2604.  
  2605.             for(i = 0; i < MAXREG; ++i)
  2606.               if(!strnicmp(RegNames[i], oldptr, len))
  2607.                 break;
  2608.  
  2609.             if(i == MAXREG)
  2610.             {
  2611.               DoError(ERR_EXPECTED_REGISTER_NAME, startlinenum);
  2612.               break;
  2613.             }
  2614.             else if(i == REG_A6)
  2615.               ap.Flags |= AMIPRAGFLAG_A6USE;
  2616.             else if(i == REG_A5)
  2617.               ap.Flags |= AMIPRAGFLAG_A5USE;
  2618.             else if(i == REG_A4)
  2619.               ap.Flags |= AMIPRAGFLAG_A4USE;
  2620.             else if(i == REG_D7)
  2621.               ap.Flags |= AMIPRAGFLAG_D7USE;
  2622.             else if(i == REG_A7)
  2623.             {
  2624.               DoError(ERR_A7_NOT_ALLOWED, startlinenum);
  2625.               break;
  2626.             }
  2627.             else if(i >= REG_FP0)
  2628.               ap.Flags |= AMIPRAGFLAG_FLOATARG;
  2629.  
  2630.             ap.Args[ap.NumArgs].ArgReg = i;
  2631.  
  2632.             for(i = 0; i < ap.NumArgs; i++)
  2633.             {
  2634.               if(ap.Args[ap.NumArgs].ArgReg == ap.Args[i].ArgReg)
  2635.               {
  2636.                 DoError(ERR_REGISTER_USED_TWICE, startlinenum);
  2637.                 break;
  2638.               }
  2639.             }
  2640.             if(i < ap.NumArgs)
  2641.               break;
  2642.  
  2643.             ++ap.NumArgs;
  2644.  
  2645.             in.pos = SkipBlanks(in.pos);
  2646.             if(*in.pos != ',' && *in.pos != '-' && *in.pos != '/' && *in.pos != /*(*/')')
  2647.             {
  2648.               DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
  2649.               break;
  2650.             }
  2651.           } while(*in.pos != /*(*/')');
  2652.  
  2653.           if(*in.pos != /*(*/')')
  2654.           {
  2655.             while(*(in.pos++))
  2656.               ++in.pos;
  2657.             continue;
  2658.           }
  2659.           else
  2660.             ++in.pos;
  2661.         }
  2662.         ap2 = (struct AmiPragma *)(AmiPragma.Last);
  2663.         if(ft && !(ft & FUNCFLAG_TAG) && ap.NumArgs != ap2->NumArgs)
  2664.           ft = 0; /* like DoPkt, handle as seperate function */
  2665.         if(ft) /* handle alias and varargs */
  2666.         {
  2667.           if(ap2->TagName || (ft & FUNCFLAG_ALIAS))
  2668.           {
  2669.             struct Pragma_AliasName *p;
  2670.  
  2671.             if((p = (struct Pragma_AliasName *)AllocListMem(sizeof(struct Pragma_AliasName))))
  2672.             {
  2673.               p->FunctionName = ap2->TagName;
  2674.               p->AliasName = ap.FuncName;
  2675.               p->Type = (ft & FUNCFLAG_TAG) ? FUNCFLAG_TAG : FUNCFLAG_NORMAL;
  2676.               AddAliasName(ap2, p, startlinenum);
  2677.             }
  2678.             else
  2679.              return 0;
  2680.           }
  2681.           else
  2682.           {
  2683.             ap2->TagName = ap.FuncName;
  2684.             ++tagfuncs;
  2685.           }
  2686.           if(ap.CallArgs != ap2->CallArgs)
  2687.           {
  2688.             if(ap2->CallArgs + 1 == ap.CallArgs && d.Args[d.NumArgs-1].Type == CPP_TYPE_VARARGS)
  2689.             {
  2690.               --ap.CallArgs;
  2691.               if(abi != ABI_M68K)
  2692.                 --ap.NumArgs;
  2693.             }
  2694.           }
  2695.           if(ap.NumArgs != ap2->NumArgs)
  2696.           {
  2697.             DoError(ERR_VARARGS_ARGUMENTS_DIFFER, startlinenum);
  2698.           }
  2699.           else if(abi == ABI_M68K)
  2700.           {
  2701.             uint32 i;
  2702.  
  2703.             for(i = 0; i < ap2->NumArgs; ++i)
  2704.             {
  2705.               if(ap2->Args[i].ArgReg != ap.Args[i].ArgReg)
  2706.               {
  2707.                 DoError(ERR_VARARGS_ARGUMENTS_DIFFER, startlinenum);
  2708.                 break;
  2709.               }
  2710.             }
  2711.           }
  2712.         }
  2713.         else if(abi == ABI_M68K)
  2714.         {
  2715.           if(ap.CallArgs != ap.NumArgs)
  2716.           { /* this is surely no longer necessary, as there wont be any varargs functions here */
  2717.             if(ap.CallArgs == ap.NumArgs+1 && d.Args[d.NumArgs-1].Type == CPP_TYPE_VARARGS)
  2718.               --ap.CallArgs;
  2719.             else
  2720.               ap.Flags |= AMIPRAGFLAG_ARGCOUNT;
  2721.           }
  2722.  
  2723.           ap.Flags |= AMIPRAGFLAG_M68K;
  2724.  
  2725.           if((Flags & FLAG_NOFPU) && (ap.Flags & AMIPRAGFLAG_FLOATARG))
  2726.             DoError(ERR_FLOATARG_NOT_ALLOWED, startlinenum);
  2727.           else if(((ap.Flags & AMIPRAGFLAG_FLOATARG) || !(Flags & FLAG_FPUONLY))
  2728.           && !(Flags & FLAG_PPCONLY))
  2729.           { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
  2730.             struct AmiPragma *d;
  2731.             if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
  2732.               return 0;
  2733.             memcpy(d, &ap, sizeof(struct AmiPragma));
  2734.             if(!CheckNames(d))
  2735.               return 0;
  2736.             AddItem(&AmiPragma, (struct ShortList *) d);
  2737.           }
  2738.         }
  2739.         else
  2740.         {
  2741.           if(!(Flags & FLAG_NOPPC))
  2742.           {
  2743.             struct AmiPragma *d;
  2744.             if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
  2745.               return 0;
  2746.             memcpy(d, &ap, sizeof(struct AmiPragma));
  2747.             if(!CheckNames(d))
  2748.               return 0;
  2749.             AddItem(&AmiPragma, (struct ShortList *) d);
  2750.           }
  2751.         }
  2752.       }
  2753.     }
  2754.  
  2755.     in.pos = SkipBlanks(in.pos);
  2756.     if(*in.pos)
  2757.       DoError(ERR_EXTRA_CHARACTERS, linenum);
  2758.     ++in.pos; /* skip '\0' */
  2759.   }
  2760.  
  2761.   if(bias)
  2762.     DoError(ERR_MISSING_SFDEND, 0);
  2763.  
  2764.   return 1;
  2765. }
  2766.  
  2767. static uint32 ScanFDFile(void)
  2768. {
  2769.   uint32 _public = 1;
  2770.   int32 bias = -1;
  2771.   uint32 linenum;
  2772.   size_t len;
  2773.   uint32 actcom = 0;
  2774.   uint32 shadowmode = 0;
  2775.   uint32 abi = ABI_M68K;
  2776.  
  2777.   if(defabi)
  2778.   {
  2779.     if(!stricmp(defabi, "M68k"))
  2780.       abi = ABI_M68K;
  2781.     else if(!stricmp(defabi, "PPC0"))
  2782.       abi = ABI_PPC0;
  2783.     else if(!stricmp(defabi, "PPC2"))
  2784.       abi = ABI_PPC2;
  2785.     else if(!stricmp(defabi, "PPC"))
  2786.       abi = ABI_PPC;
  2787.     else
  2788.       DoError(ERR_UNKNOWN_ABI, 0, defabi);
  2789.   }
  2790.  
  2791.   if(in.size > 10 && in.pos[0] == '=' && in.pos[1] == '=')
  2792.     return ScanSFDFile(abi);
  2793.  
  2794. #ifdef DEBUG_OLD
  2795.   printf("ScanFDFile:\n");
  2796. #endif
  2797.  
  2798.   for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
  2799.   {
  2800.     if(*in.pos == '*')          /*  Comment   */
  2801.     {
  2802.       strptr oldpos = in.pos;
  2803. #ifdef DEBUG_OLD
  2804.   printf("ScanFDFile: found a comment\n");
  2805. #endif
  2806.       in.pos = SkipBlanks(in.pos+1);
  2807.       if(!strnicmp(in.pos, "notagcall", 9))
  2808.       {
  2809.         struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.Last;
  2810.         
  2811.         if(ap->TagName)
  2812.         {
  2813.           --tagfuncs; ap->TagName = 0;
  2814.           ap->Flags &= ~(AMIPRAGFLAG_OWNTAGFUNC);
  2815.         }
  2816.         in.pos = SkipBlanks(in.pos + 9);
  2817.       }
  2818.       else if(!strnicmp(in.pos, "tagcall", 7))  /*  Tag to create?  */
  2819.       {
  2820.         struct AmiPragma *prevpragma = (struct AmiPragma *) AmiPragma.Last;
  2821.  
  2822.         in.pos = SkipBlanks(in.pos + 7);
  2823.         if(!prevpragma)
  2824.         {
  2825.           DoError(ERR_TAG_DEF_WITHOUT_PRAGMA, linenum);
  2826.           ++in.pos;
  2827.           continue;
  2828.         }
  2829.  
  2830.         if(!prevpragma->NumArgs)
  2831.         {
  2832.           DoError(ERR_TAGFUNC_NEEDS_ARGUMENT, linenum);
  2833.           ++in.pos;
  2834.           continue;
  2835.         }
  2836.  
  2837.         /* Get the tag functions name. */
  2838.  
  2839.         if(!prevpragma->TagName && (_public || (Flags & FLAG_PRIVATE)))
  2840.           ++tagfuncs;
  2841.  
  2842.         if(*in.pos)
  2843.         {
  2844.           strptr oldptr, tptr = prevpragma->TagName;
  2845.         
  2846.           len = strlen(prevpragma->FuncName)+strlen(in.pos)+1;
  2847.           if(!(prevpragma->TagName = DupString(prevpragma->FuncName, len)))
  2848.             return 0;
  2849.  
  2850.           if(*in.pos == '-')
  2851.           {
  2852.             strptr removeptr;
  2853.  
  2854.             oldptr = in.pos = SkipBlanks(in.pos+1);
  2855.             in.pos = SkipName(in.pos);
  2856.             if((len = in.pos-oldptr))
  2857.             {
  2858.               removeptr = prevpragma->TagName+strlen(prevpragma->TagName)-len;
  2859.               if(strncmp(removeptr, oldptr, len))
  2860.               {
  2861. #ifdef DEBUG_OLD
  2862.   printf("ScanFDFile: *tagcall -: %s, %s, %ld\n", removeptr, oldptr, len);
  2863. #endif
  2864.                 DoError(ERR_CANNOT_CONVERT_PRAGMA_TAGCALL, linenum);
  2865.                 prevpragma->TagName = tptr;
  2866.                 ++in.pos;
  2867.                 continue;
  2868.               }
  2869.  
  2870.               *removeptr = '\0';
  2871.             }
  2872.             in.pos = SkipBlanks(in.pos);
  2873.           }
  2874.           if(*in.pos == '+')
  2875.             in.pos = SkipBlanks(in.pos+1);
  2876.           else
  2877.             *in.pos = toupper(*in.pos);
  2878.  
  2879.           in.pos = SkipName((oldptr = in.pos));
  2880.           len = in.pos-oldptr;
  2881.           if(len)
  2882.           {
  2883.             uint32 a = strlen(prevpragma->TagName);
  2884.             memcpy(prevpragma->TagName+a, oldptr, len);
  2885.             prevpragma->TagName[a+len] = '\0';
  2886.           }
  2887.         }
  2888.         else if(!prevpragma->TagName)
  2889.         {
  2890.           len = strlen(prevpragma->FuncName);
  2891.           if(!(prevpragma->TagName = DupString(prevpragma->FuncName, len+4)))
  2892.             return 0;
  2893.           memcpy(prevpragma->TagName + len, "Tags", 5);
  2894.         }
  2895.       }
  2896.       else
  2897.       {
  2898.         if(actcom)
  2899.           *(oldpos-1) = '\n';
  2900.         else
  2901.         {
  2902.           struct Comment *d;
  2903.           if(!(d = (struct Comment *) NewItem(&Comment)))
  2904.             return 0;
  2905.           d->Bias = bias;
  2906.           d->Data = oldpos;
  2907.           d->ReservedNum = 0;
  2908.           d->Version = 0;
  2909.           d->Private = _public ? 0 : 1;
  2910.           AddItem(&Comment, (struct ShortList *) d);
  2911.           actcom = 1;
  2912.         }
  2913.         while(*in.pos)
  2914.           ++in.pos;
  2915.       }
  2916.     }
  2917.     else if(*in.pos == '#' && in.pos[1] == '#')
  2918.     {
  2919.       in.pos += 2;
  2920.       actcom = 0; /* no Comment */
  2921.  
  2922.       if(!strnicmp(in.pos, "base", 4))
  2923.       {
  2924.         strptr oldptr;
  2925.  
  2926. #ifdef DEBUG_OLD
  2927.   printf("ScanFDFile: found ##base\n");
  2928. #endif
  2929.         if(!(Flags & FLAG_BASENAME))
  2930.         {
  2931.           if(BaseName)
  2932.             DoError(ERR_BASENAME_DECLARED_TWICE, linenum);
  2933.  
  2934.           in.pos = SkipBlanks(in.pos+4);
  2935.           if(*in.pos != '_')
  2936.             DoError(ERR_EXPECTED_SLASH_IN_BASENAME, linenum);
  2937.           else
  2938.             ++in.pos;
  2939.  
  2940.           BaseName = oldptr = in.pos;
  2941.           in.pos = SkipName(in.pos);
  2942.           if(!(in.pos-oldptr))
  2943.             DoError(ERR_EXPECTED_BASENAME, linenum);
  2944.         }
  2945.         else
  2946.         {
  2947.           DoError(ERR_COMMANDLINE_BASENAME, linenum);
  2948.           while(*in.pos)
  2949.             ++in.pos;
  2950.         }
  2951.       }
  2952.       else if(!strnicmp(in.pos, "bias", 4))
  2953.       {
  2954.         strptr ptr;
  2955.         int32 newbias;
  2956.  
  2957. #ifdef DEBUG_OLD
  2958.   printf("ScanFDFile: found ##bias\n");
  2959. #endif
  2960.         in.pos += 5;
  2961.         newbias = strtol(in.pos, &ptr, 10);
  2962.         if(ptr == in.pos)
  2963.           DoError(ERR_EXPECTED_BIAS_VALUE, linenum);
  2964.         else if(newbias < 0)
  2965.         {
  2966.           DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE, linenum);
  2967.           bias = -newbias;
  2968.         }
  2969.         else
  2970.           bias = newbias;
  2971.         in.pos = SkipName(in.pos);
  2972.       }
  2973.       else if(!strnicmp(in.pos, "end", 3))
  2974.       {
  2975.         bias = 0; break;
  2976.       }
  2977.       else if(!strnicmp(in.pos, "shadow", 6)) /* introduced by Storm */
  2978.       {
  2979.         in.pos += 6;
  2980.         if(bias == -1 || !AmiPragma.First)
  2981.           DoError(ERR_EARLY_SHADOW, linenum);
  2982.         else
  2983.         {
  2984.           bias -= BIAS_OFFSET;
  2985.           shadowmode = 1;
  2986.         }
  2987.       }
  2988.       else if(!strnicmp(in.pos, "public", 6))
  2989.       {
  2990.         in.pos += 6;
  2991.         _public = 1;
  2992.       }
  2993.       else if(!strnicmp(in.pos, "private", 7))
  2994.       {
  2995.         in.pos += 7;
  2996.         _public = 0;
  2997.       }
  2998.       else if(!strnicmp(in.pos, "abi", 3))
  2999.       {
  3000. #ifdef DEBUG_OLD
  3001.   printf("ScanFDFile: found ##abi\n");
  3002. #endif
  3003.         in.pos = SkipBlanks(in.pos+3);
  3004.         if(!strnicmp(in.pos, "M68k", 4))
  3005.         {
  3006.           abi = ABI_M68K; in.pos += 4;
  3007.         }
  3008.         else if(!strnicmp(in.pos, "PPC0", 4))
  3009.         {
  3010.           abi = ABI_PPC0; in.pos += 4;
  3011.         }
  3012.         else if(!strnicmp(in.pos, "PPC2", 4))
  3013.         {
  3014.           abi = ABI_PPC2; in.pos += 4;
  3015.         }
  3016.         else if(!strnicmp(in.pos, "PPC", 3))
  3017.         {
  3018.           abi = ABI_PPC; in.pos += 3;
  3019.         }
  3020.         else
  3021.           DoError(ERR_UNKNOWN_ABI, linenum, in.pos);
  3022.       }
  3023.       else
  3024.         DoError(ERR_UNKNOWN_DIRECTIVE, linenum, in.pos-2);
  3025.     }
  3026.     else
  3027.     {
  3028.       strptr oldptr;
  3029.       uint32 maxreg;
  3030.       struct AmiPragma ap, *ap2;
  3031.  
  3032. #ifdef DEBUG_OLD
  3033.   printf("ScanFDFile: scan Function\n");
  3034. #endif
  3035.       memset(&ap, 0, sizeof(struct AmiPragma));
  3036.       actcom = 0;
  3037.  
  3038.       oldptr = in.pos = SkipBlanks(in.pos);
  3039.       in.pos = SkipName(oldptr);
  3040.       if(!(len = in.pos-oldptr))
  3041.       {
  3042.         DoError(ERR_MISSING_FUNCTION_NAME, linenum);
  3043.         ++in.pos;
  3044.         continue;
  3045.       }
  3046.  
  3047.       ap.FuncName = oldptr;
  3048.  
  3049.       in.pos = SkipBlanks(in.pos);
  3050.       if(*in.pos != '('/*)*/)
  3051.       {
  3052.         DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
  3053.         ++in.pos;
  3054.         continue;
  3055.       }
  3056.  
  3057.       oldptr[len] = '\0'; /* create c string of FunctionName */
  3058.  
  3059. #ifdef DEBUG_OLD
  3060.   printf("ScanFDFile: found function %s\n", ap.FuncName);
  3061. #endif
  3062.  
  3063.       maxreg = ((abi == ABI_M68K) ? MAXREG-2 : MAXREGPPC);
  3064.       do
  3065.       {
  3066.         oldptr = in.pos = SkipBlanks(in.pos+1);
  3067.  
  3068.         if(*in.pos == '*') /* strange OS3.9 files */
  3069.         {
  3070.           DoError(ERR_ILLEGAL_CHARACTER_DETECTED, linenum);
  3071.           oldptr = in.pos = SkipBlanks(in.pos+1);
  3072.         }
  3073.  
  3074.         if(*in.pos == /*(*/')' && !ap.CallArgs)
  3075.           break;
  3076.  
  3077.         if(ap.CallArgs >= maxreg)
  3078.         {
  3079.           DoError(ERR_TO_MUCH_ARGUMENTS, linenum); break;
  3080.         }
  3081.  
  3082.         in.pos = SkipName(oldptr);
  3083.         if(*in.pos == '*')
  3084.           ++in.pos;
  3085.         if(!(len = in.pos-oldptr))
  3086.         {
  3087.           DoError(ERR_EXPECTED_ARGUMENT_NAME, linenum);
  3088.           ap.Args[ap.CallArgs++].ArgName = 0;
  3089.         }
  3090.         else
  3091.         {
  3092.           ap.Args[ap.CallArgs++].ArgName = oldptr;
  3093.           oldptr = in.pos;
  3094.           in.pos = SkipBlanks(in.pos);
  3095.         }
  3096.         if(*in.pos != ',' && *in.pos != '/' && *in.pos != /*(*/')')
  3097.         {
  3098.           DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
  3099.           break;
  3100.         }
  3101.         if(*in.pos != /*(*/')') /* create c string ending */
  3102.           *oldptr = '\0';
  3103.       } while(*in.pos != /*(*/')');
  3104.  
  3105.       if(*in.pos != /*(*/')')
  3106.       {
  3107.         while(*(in.pos++))
  3108.           ++in.pos;
  3109.         continue;
  3110.       }
  3111.       else
  3112.         *oldptr = '\0'; /* create c string ending for last argument */
  3113.  
  3114.       if(bias == -1)
  3115.       {
  3116.         DoError(ERR_ASSUMING_BIAS_OF_30, linenum);
  3117.         bias = BIAS_START;
  3118.       }
  3119.  
  3120.       ap.Bias = bias;
  3121.       ap.Abi = abi;
  3122.       ap.Line = linenum;
  3123.       bias += BIAS_OFFSET;
  3124.  
  3125.       if(_public)
  3126.         ap.Flags |= AMIPRAGFLAG_PUBLIC;
  3127.  
  3128.       in.pos = SkipBlanks(in.pos+1);
  3129.  
  3130.       if(*in.pos || ap.CallArgs)
  3131.       /* support for FD's without second empty bracket pair */
  3132.       {
  3133.         if(*in.pos != '('/*)*/)
  3134.         {
  3135.           DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
  3136.           ++in.pos;
  3137.           continue;
  3138.         }
  3139.  
  3140.         if(abi == ABI_M68K)
  3141.         {
  3142.           do
  3143.           {
  3144.             uint32 i;
  3145.  
  3146.             oldptr = in.pos = SkipBlanks(in.pos + 1);
  3147.  
  3148.             if(*in.pos == /*(*/')' && !ap.NumArgs)
  3149.               break;
  3150.  
  3151.             in.pos = SkipName(oldptr);
  3152.             len = in.pos-oldptr;
  3153.  
  3154.             for(i = 0; i < MAXREG; ++i)
  3155.               if(!strnicmp(RegNames[i], oldptr, len))
  3156.                 break;
  3157.  
  3158.             if(i == MAXREG)
  3159.             {
  3160.               DoError(ERR_EXPECTED_REGISTER_NAME, linenum);
  3161.              break;
  3162.             }
  3163.             else if(i == REG_A6)
  3164.               ap.Flags |= AMIPRAGFLAG_A6USE;
  3165.             else if(i == REG_A5)
  3166.               ap.Flags |= AMIPRAGFLAG_A5USE;
  3167.             else if(i == REG_A4)
  3168.               ap.Flags |= AMIPRAGFLAG_A4USE;
  3169.             else if(i == REG_D7)
  3170.               ap.Flags |= AMIPRAGFLAG_D7USE;
  3171.             else if(i == REG_A7)
  3172.             {
  3173.               DoError(ERR_A7_NOT_ALLOWED, linenum);
  3174.               break;
  3175.             }
  3176.             else if(i >= REG_FP0)
  3177.               ap.Flags |= AMIPRAGFLAG_FLOATARG;
  3178.  
  3179.             ap.Args[ap.NumArgs].ArgReg = i;
  3180.  
  3181.             for(i = 0; i < ap.NumArgs; i++)
  3182.             {
  3183.               if(ap.Args[ap.NumArgs].ArgReg == ap.Args[i].ArgReg)
  3184.               {
  3185.                 DoError(ERR_REGISTER_USED_TWICE, linenum);
  3186.                 break;
  3187.               }
  3188.             }
  3189.             if(i < ap.NumArgs)
  3190.               break;
  3191.  
  3192.             ++ap.NumArgs;
  3193.  
  3194.             in.pos = SkipBlanks(in.pos);
  3195.             if(*in.pos != ',' && *in.pos != '/' && *in.pos != /*(*/')')
  3196.             {
  3197.               DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
  3198.               break;
  3199.             }
  3200.           } while(*in.pos != /*(*/')');
  3201.  
  3202.           if(*in.pos != /*(*/')')
  3203.           {
  3204.             while(*(in.pos++))
  3205.               ++in.pos;
  3206.             continue;
  3207.           }
  3208.           else
  3209.             ++in.pos;
  3210.         }
  3211.         else
  3212.         {
  3213.           while(*in.pos && *in.pos != /*(*/')')
  3214.            ++in.pos;
  3215.           if(*in.pos != /*(*/')')
  3216.           {
  3217.             DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
  3218.             ++in.pos;
  3219.             continue;
  3220.           }
  3221.           ++in.pos;
  3222.           ap.NumArgs = ap.CallArgs;
  3223.  
  3224.           ap.Flags |= AMIPRAGFLAG_PPC;
  3225.           if(abi == ABI_PPC0)
  3226.             ap.Flags |= AMIPRAGFLAG_PPC0;
  3227.           else if(abi == ABI_PPC2)
  3228.             ap.Flags |= AMIPRAGFLAG_PPC2;
  3229.         }
  3230.       }
  3231.       else
  3232.         DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
  3233.  
  3234.       ap2 = (struct AmiPragma *)(AmiPragma.Last);
  3235.       if(shadowmode)
  3236.       {
  3237.         if(ap2->TagName && !(ap2->Flags & AMIPRAGFLAG_OWNTAGFUNC))
  3238.         {
  3239.           struct Pragma_AliasName *p;
  3240.           DoError(ERR_DOUBLE_VARARGS, linenum);
  3241.           
  3242.           if((p = (struct Pragma_AliasName *)AllocListMem(sizeof(struct Pragma_AliasName))))
  3243.           {
  3244.             p->FunctionName = ap2->TagName;
  3245.             p->AliasName = ap.FuncName;
  3246.             p->Type = FUNCFLAG_TAG;
  3247.             AddAliasName(ap2, p, linenum);
  3248.           }
  3249.           else
  3250.             return 0;
  3251. #ifdef DEBUG_OLD
  3252.   printf("ScanFDFile: StormFD mode, tag func alias: %s\n", ap2->TagName);
  3253. #endif
  3254.         }
  3255.         else
  3256.         {
  3257. #ifdef DEBUG_OLD
  3258.   printf("ScanFDFile: StormFD mode, tag func: %s\n", ap2->TagName);
  3259. #endif
  3260.           ap2->Flags &= ~(AMIPRAGFLAG_OWNTAGFUNC);
  3261.           ap2->TagName = ap.FuncName;
  3262.           ++tagfuncs;
  3263.         }
  3264.         if(ap.NumArgs != ap2->NumArgs)
  3265.           DoError(ERR_VARARGS_ARGUMENTS_DIFFER, linenum);
  3266.         else if(abi == ABI_M68K)
  3267.         {
  3268.           uint32 i;
  3269.  
  3270.           for(i = 0; i < ap2->NumArgs; ++i)
  3271.           {
  3272.             if(ap2->Args[i].ArgReg != ap.Args[i].ArgReg)
  3273.             {
  3274.               DoError(ERR_VARARGS_ARGUMENTS_DIFFER, linenum);
  3275.               break;
  3276.             }
  3277.           }
  3278.         }
  3279.       }
  3280.       else if(ap2 && ap2->Bias == ap.Bias && ap2->NumArgs == ap.NumArgs) /* handle them as alias instead seperate */
  3281.       {
  3282.         struct Pragma_AliasName *p;
  3283.  
  3284.         if((p = (struct Pragma_AliasName *)AllocListMem(sizeof(struct Pragma_AliasName))))
  3285.         {
  3286.           p->FunctionName = ap2->TagName;
  3287.           p->AliasName = ap.FuncName;
  3288.           p->Type = FUNCFLAG_NORMAL;
  3289.           AddAliasName(ap2, p, linenum);
  3290.         }
  3291.         if(abi == ABI_M68K)
  3292.         {
  3293.           uint32 i;
  3294.  
  3295.           for(i = 0; i < ap2->NumArgs; ++i)
  3296.           {
  3297.             if(ap2->Args[i].ArgReg != ap.Args[i].ArgReg)
  3298.             {
  3299.               DoError(ERR_VARARGS_ARGUMENTS_DIFFER, linenum);
  3300.               break;
  3301.             }
  3302.           }
  3303.         }
  3304.       }
  3305.       else
  3306.       {
  3307.         if((_public || (Flags & FLAG_PRIVATE)) && !MakeTagFunction(&ap))
  3308.           return 0;
  3309.         else      /* check the alias names */
  3310.         {
  3311.           uint32 i = 0;
  3312.  
  3313.           while(Pragma_AliasNames[i].FunctionName)
  3314.           {
  3315.             if(!strcmp(ap.FuncName, Pragma_AliasNames[i].FunctionName) ||
  3316.             (ap.TagName && !strcmp(ap.TagName, Pragma_AliasNames[i].FunctionName)))
  3317.             {
  3318.               AddAliasName(&ap, (struct Pragma_AliasName *) &Pragma_AliasNames[i], linenum);
  3319.             }
  3320.             ++i;
  3321.           }
  3322.         }
  3323.  
  3324.         if(abi == ABI_M68K)
  3325.         {
  3326.           if(ap.CallArgs != ap.NumArgs)
  3327.             ap.Flags |= AMIPRAGFLAG_ARGCOUNT;
  3328.  
  3329.           ap.Flags |= AMIPRAGFLAG_M68K;
  3330.  
  3331.           if((Flags & FLAG_NOFPU) && (ap.Flags & AMIPRAGFLAG_FLOATARG))
  3332.             DoError(ERR_FLOATARG_NOT_ALLOWED, linenum);
  3333.           else if(((ap.Flags & AMIPRAGFLAG_FLOATARG) || !(Flags & FLAG_FPUONLY))
  3334.           && !(Flags & FLAG_PPCONLY))
  3335.           { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
  3336.             struct AmiPragma *d;
  3337.             if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
  3338.               return 0;
  3339.             memcpy(d, &ap, sizeof(struct AmiPragma));
  3340.             if(!CheckNames(d))
  3341.               return 0;
  3342.             AddItem(&AmiPragma, (struct ShortList *) d);
  3343.             if(!SpecialFuncs())
  3344.               return 0;
  3345.           }
  3346.         }
  3347.         else
  3348.         {
  3349.           if(!(Flags & FLAG_NOPPC))
  3350.           {
  3351.             struct AmiPragma *d;
  3352.             if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
  3353.               return 0;
  3354.             memcpy(d, &ap, sizeof(struct AmiPragma));
  3355.             if(!CheckNames(d))
  3356.               return 0;
  3357.             AddItem(&AmiPragma, (struct ShortList *) d);
  3358. /*
  3359.             if(!SpecialFuncs())
  3360.               return 0;
  3361. */
  3362.           }
  3363.         }
  3364.       }
  3365.       shadowmode = 0;
  3366.     }
  3367.  
  3368.     in.pos = SkipBlanks(in.pos);
  3369.     if(*in.pos)
  3370.       DoError(ERR_EXTRA_CHARACTERS, linenum);
  3371.     ++in.pos; /* skip '\0' */
  3372.   }
  3373.  
  3374.   if(bias)
  3375.     DoError(ERR_MISSING_END, 0);
  3376.  
  3377.   return 1;
  3378. }
  3379.  
  3380. static int32 ScanTypes(strptr ptr, uint32 size)
  3381. {
  3382.   struct CPP_ExternNames *a = 0, *b = 0;
  3383.   strptr endptr = ptr+size;
  3384.   int32 line;
  3385.  
  3386.   for(line = 1; ptr < endptr; ++line)
  3387.   {
  3388.     struct CPP_ExternNames *n;
  3389.  
  3390.     if(*ptr == '*') /* skip comments */
  3391.     {
  3392.       while(ptr < endptr && *(ptr++) != '\n')
  3393.         ;
  3394.     }
  3395.     else if((n = (struct CPP_ExternNames *)
  3396.       AllocListMem(sizeof(struct CPP_ExternNames))))
  3397.     {
  3398.       strptr wptr;
  3399.  
  3400.       n->Type = ptr; /* store start */
  3401.  
  3402.       while(ptr < endptr && *ptr != ':' && *ptr != '\n' && *ptr != '\t' && *ptr != ' ')
  3403.         ++ptr;
  3404.       wptr = SkipBlanks(ptr);
  3405.       if(*(wptr++) != ':')
  3406.         return line;
  3407.       *ptr = 0;
  3408.  
  3409.       n->NameType.StructureName = n->Type;
  3410.       n->NameType.StructureLength = ptr-n->Type; /* for struct ! types */
  3411.  
  3412.       if(!GetCPPType(&n->NameType, (ptr = SkipBlanks(wptr)), 0, 1))
  3413.         return line;
  3414. #ifdef DEBUG_OLD
  3415.   printf("'%20s', slen %2ld, typelen %3ld, pntd %ld, type %lc, sn '%.3s'\n",
  3416.   n->Type, n->NameType.StructureLength, n->NameType.FullLength,
  3417.   n->NameType.PointerDepth, n->NameType.Type ? n->NameType.Type : 's',
  3418.   n->NameType.StructureName ? n->NameType.StructureName : "<e>");
  3419. #endif
  3420.       ptr = SkipBlanks(n->NameType.TypeStart+n->NameType.FullLength);
  3421.       if(*(ptr++) != '\n')
  3422.       {
  3423. #ifdef DEBUG_OLD
  3424.   printf("%.30s\n", ptr);
  3425. #endif
  3426.         return line;
  3427.       }
  3428.  
  3429.       if(!a)
  3430.         b = n;
  3431.       else
  3432.         a->Next = n;
  3433.       a = n;
  3434.     }
  3435.     else
  3436.       return -1;
  3437.   }
  3438.   extnames = b; /* now store the list */
  3439.   return 0;
  3440. }
  3441.  
  3442. static void FindHeader(void)
  3443. {
  3444.   strptr str = HEADER;
  3445.   uint32 mode = 0;
  3446.  
  3447.   do
  3448.   {
  3449.     if(!mode)
  3450.       HEADER = str;
  3451.  
  3452.     if(*str == '/')
  3453.     {
  3454.       ++str;
  3455.       if(*str == '*')
  3456.       {
  3457.         mode = 2; break;
  3458.       }
  3459.       else if(*str == '/')
  3460.         mode = 1;
  3461.     }
  3462.     else if(*str == '*' || *str == ';')
  3463.       mode = 1;
  3464.     else if(*str == '{'/*}*/)
  3465.     {
  3466.       mode = 3; break;
  3467.     }
  3468.     else if(*str == '('/*)*/ && *(++str) == '*')
  3469.     {
  3470.       mode = 4; break;
  3471.     }
  3472.     else if(mode)
  3473.       break;
  3474.     while(*str && *(str++) != '\n')
  3475.       ;
  3476.   } while(*str);
  3477.  
  3478.   if(mode == 2)
  3479.   {
  3480.     while(*str && (*(str-1) != '*' || *str != '/'))
  3481.       ++str;
  3482.     while(*str && *(str++) != '\n')
  3483.       ;
  3484.   }
  3485.   else if(mode == 3)
  3486.   {
  3487.     while(*str && *str != /*{*/'}')
  3488.       ++str;
  3489.     while(*str && *(str++) != '\n')
  3490.       ;
  3491.   }
  3492.   else if(mode == 4)
  3493.   {
  3494.     while(*str && (*(str-1) != '*' || *str != /*(*/')'))
  3495.       ++str;
  3496.     while(*str && *(str++) != '\n')
  3497.       ;
  3498.   }
  3499.  
  3500.   if(mode)
  3501.     headersize = str-HEADER;
  3502.   else
  3503.   {
  3504.     HEADER = 0; headersize = 0;
  3505.   }
  3506. }
  3507.  
  3508. /* returns decrement data in bits 0-15 and increment data in bits 16-31 */
  3509. static uint32 GetRegisterData(struct AmiPragma *ap)
  3510. {
  3511. /* usage of result:
  3512.     48E7 <lower word>    MOVEM.L <registers>,-(A7) ; D0 is bit 15
  3513.     4CDF <upper word>    MOVEM.L (A7)+,<registers> ; D0 is bit 0
  3514. */
  3515.   register uint32 i, data = 0, reg;
  3516.  
  3517.   for(i = 0; i < ap->NumArgs; ++i)
  3518.   {
  3519.     if((reg = ap->Args[i].ArgReg) <= REG_FP0)
  3520.     {
  3521.       if(reg >= 10 || (reg >= 2 &&  reg <= 7)) /* A2-A7 and D2-D7 */
  3522.         data |= (1 << (reg + 16)) + (1 << (15 - reg));
  3523.     }
  3524.   }
  3525.   if(data)      /* set A6 only when other register used */
  3526.     data |= 0x40000002;
  3527.   return data;
  3528. }
  3529.  
  3530. static uint16 GetFRegisterData(struct AmiPragma *ap)
  3531. {
  3532. /* usage of result:
  3533.     F227 <upper byte>    FMOVEM.X <registers>,-(A7) ; FP0 is bit 0
  3534.     F21F <lower byte>    FMOVEM.X (A7)+,<registers> ; FP0 is bit 7
  3535. */
  3536.   register uint32 i, reg;
  3537.   register uint16 data = 0;
  3538.  
  3539.   for(i = 0; i < ap->NumArgs; ++i)
  3540.   {
  3541.     if((reg = ap->Args[i].ArgReg) >= REG_FP2)
  3542.     {
  3543.       reg -= REG_FP0;
  3544.       data |= (1 << (reg + 8)) + (1 << (7 - reg));
  3545.     }
  3546.   }
  3547.   return data;
  3548. }
  3549.  
  3550. static uint32 OutputXDEF(uint32 offset, strptr format, ...)
  3551. {
  3552.   uint8 buf[150];
  3553.   va_list a;
  3554.   size_t i;
  3555.  
  3556.   va_start(a, format);
  3557.   i = vsprintf((strptr)(buf+4), format, a);
  3558.   va_end(a);
  3559.   while(i&3)
  3560.     buf[4+i++] = 0;
  3561.   EndPutM32(buf+4+i, offset); /* the definition offset */
  3562.  
  3563.   EndPutM32(buf, (EXT_DEF<<24) + (i>>2));
  3564.  
  3565.   return DoOutputDirect(buf, i+8);
  3566. }
  3567.  
  3568. static uint32 OutputXREF(uint32 offset, uint32 type, strptr format, ...)
  3569. {
  3570.   uint8 buf[150];
  3571.   va_list a;
  3572.   size_t i;
  3573.  
  3574.   va_start(a, format);
  3575.   i = vsprintf((strptr)(buf+4), format, a);
  3576.   va_end(a);
  3577.   while(i&3)
  3578.     buf[4+i++] = 0;
  3579.   EndPutM32(buf+4+i, 1); /* 1 reference */
  3580.   EndPutM32(buf+8+i, offset); /* the definition offset */
  3581.  
  3582.   EndPutM32(buf, (type << 24) + (i>>2));
  3583.  
  3584.   return DoOutputDirect(buf, i+12);
  3585. }
  3586.  
  3587. static uint32 OutputXREF2(uint32 offset1, uint32 offset2, uint32 type, strptr format, ...)
  3588. {
  3589.   uint8 buf[150];
  3590.   va_list a;
  3591.   size_t i;
  3592.  
  3593.   va_start(a, format);
  3594.   i = vsprintf((strptr)(buf+4), format, a);
  3595.   va_end(a);
  3596.   while(i&3)
  3597.     buf[4+i++] = 0;
  3598.   EndPutM32(buf+4+i, 2); /* 2 references */
  3599.   EndPutM32(buf+8+i, offset1); /* the definition offset */
  3600.   EndPutM32(buf+12+i, offset2); /* the definition offset */
  3601.  
  3602.   EndPutM32(buf, (type << 24) + (i>>2));
  3603.  
  3604.   return DoOutputDirect(buf, i+16);
  3605. }
  3606.  
  3607. static uint32 OutputSYMBOL(uint32 offset, strptr format, ...)
  3608. {
  3609.   va_list a;
  3610.   uint8 buf[150];
  3611.   size_t i;
  3612.  
  3613.   va_start(a, format);
  3614.   i = vsprintf((strptr)(buf+4), format, a);
  3615.   va_end(a);
  3616.   while(i&3)
  3617.     buf[4+i++] = 0;
  3618.   EndPutM32(buf+4+i, offset);
  3619.  
  3620.   EndPutM32(buf, (0 << 24) + (i>>2));
  3621.  
  3622.   return DoOutputDirect(buf, i+8);
  3623. }
  3624.  
  3625. static uint8 *AsmStackCopy(uint8 *data, struct AmiPragma *ap, uint32 flags, uint32 ofs)
  3626. {
  3627.   uint32 i, j, k, l, tofs;
  3628.  
  3629.   if(Flags & FLAG_PASCAL)
  3630.   {
  3631.     k = ap->NumArgs;
  3632.  
  3633.     while(k)
  3634.     {
  3635.       if(ap->Args[k-1].ArgReg >= REG_FP0)
  3636.       {
  3637.         struct ClibData *cd; 
  3638.  
  3639.         cd = GetClibFunc(ap->FuncName, ap, flags);
  3640.         EndPutM16Inc(data, 0xF22F);     /* FMOVE.? offs(A7),FPx */
  3641.  
  3642.         if(cd && IsCPPType(&cd->Args[k-1], CPP_TYPE_DOUBLE))
  3643.         {
  3644.           EndPutM16Inc(data, 0x5400 + ((ap->Args[--k].ArgReg-REG_FP0)<<7));
  3645.           EndPutM16Inc(data, ofs<<2); /* one double needs two longs */
  3646.           ofs += 2;
  3647.         }
  3648.         else
  3649.         {
  3650.           if(!cd || !IsCPPType(&cd->Args[k-1], CPP_TYPE_FLOAT))
  3651.             DoError(ERR_LONG_DOUBLE, ap->Line);
  3652.           EndPutM16Inc(data, 0x4400 + ((ap->Args[--k].ArgReg-REG_FP0)<<7));
  3653.           EndPutM16Inc(data, (ofs++) << 2);
  3654.         }
  3655.       }
  3656.       else if((k >= 2) && (ap->Args[k-1].ArgReg < ap->Args[k-2].ArgReg)
  3657.       && ap->Args[k-2].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
  3658.       {
  3659.         l = 0; tofs = ofs;
  3660.         do
  3661.         {
  3662.           j = ap->Args[--k].ArgReg;
  3663.  
  3664.           ++ofs;
  3665.           l |= 1 << j;
  3666.         } while(k && j < ap->Args[k-1].ArgReg && ap->Args[k-1].ArgReg < REG_FP0);
  3667.         EndPutM16Inc(data, 0x4CEF);     /* MOVEM.L offs(A7),xxx */
  3668.         EndPutM16Inc(data, l);
  3669.         EndPutM16Inc(data, tofs << 2);   /* store start offset */
  3670.       }
  3671.       else
  3672.       {
  3673.         l = 0x202F;                     /* MOVE.L offs(A7),xxx */
  3674.  
  3675.         if((j = ap->Args[--k].ArgReg) > 7)
  3676.         {
  3677.           l |= (1<<6); j -= 8;          /* set MOVEA bit */
  3678.         }
  3679.         EndPutM16Inc(data, l | (j << 9)); /* set destination register and store */
  3680.         EndPutM16Inc(data, (ofs++) << 2);
  3681.       }
  3682.     }
  3683.   }
  3684.   else
  3685.   {
  3686.     i = 0;
  3687.  
  3688.     k = ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0);
  3689.  
  3690.     while(i < k)
  3691.     {
  3692.       if(ap->Args[i].ArgReg >= REG_FP0)
  3693.       {
  3694.         struct ClibData *cd; 
  3695.  
  3696.         cd = GetClibFunc(ap->FuncName, ap, flags);
  3697.         EndPutM16Inc(data, 0xF22F);     /* FMOVE.? offs(A7),FPx */
  3698.  
  3699.         if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_DOUBLE))
  3700.         {
  3701.           EndPutM16Inc(data, 0x5400 + ((ap->Args[i++].ArgReg-REG_FP0)<<7));
  3702.           EndPutM16Inc(data, ofs<<2); /* one double needs two longs */
  3703.           ofs += 2;
  3704.         }
  3705.         else
  3706.         {
  3707.           if(!cd || !IsCPPType(&cd->Args[i], CPP_TYPE_FLOAT))
  3708.             DoError(ERR_LONG_DOUBLE, ap->Line);
  3709.           EndPutM16Inc(data, 0x4400 + ((ap->Args[i++].ArgReg-REG_FP0)<<7));
  3710.           EndPutM16Inc(data, (ofs++) << 2);
  3711.         }
  3712.       }
  3713.       else if(((k - i) >= 2) && (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg)
  3714.       && ap->Args[i+1].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
  3715.       {
  3716.         l = 0; tofs = ofs;
  3717.         do
  3718.         {
  3719.           j = ap->Args[i++].ArgReg;
  3720.  
  3721.           ++ofs;
  3722.           l |= 1 << j;
  3723.         } while(i < k && j < ap->Args[i].ArgReg && ap->Args[i].ArgReg < REG_FP0);
  3724.         EndPutM16Inc(data, 0x4CEF);     /* MOVEM.L offs(A7),xxx */
  3725.         EndPutM16Inc(data, l);          /* Store MOVEM.L data */
  3726.         EndPutM16Inc(data, tofs << 2);  /* store start offset */
  3727.       }
  3728.       else
  3729.       {
  3730.         l = 0x202F;                     /* MOVE.L offs(A7),xxx */
  3731.  
  3732.         if((j = ap->Args[i++].ArgReg) > 7)
  3733.         {
  3734.           l |= (1<<6); j -= 8;          /* set MOVEA bit */
  3735.         }
  3736.         EndPutM16Inc(data, l | (j << 9)); /* set destination register and store */
  3737.         EndPutM16Inc(data, (ofs++) << 2);
  3738.       }
  3739.     }
  3740.  
  3741.     if(i < ap->NumArgs)
  3742.     {
  3743.       if((j = ap->Args[i].ArgReg) > 7)
  3744.       {
  3745.         EndPutM16Inc(data, 0x41EF | ((j-8) << 9)); /* LEA xxx(A7),Ax */
  3746.         EndPutM16Inc(data, ofs << 2);
  3747.       }
  3748.       else if(ofs == 2)
  3749.       {
  3750.         EndPutM16Inc(data, 0x200F | (j << 9));  /* MOVE.L A7,Dx */
  3751.         EndPutM16Inc(data, 0x5080 | j);         /* ADDQ.L #8,Dx */
  3752.       }
  3753.       else
  3754.       {
  3755.         EndPutM16Inc(data, 0x486F);             /* PEA xxx(A7) */
  3756.         EndPutM16Inc(data, ofs << 2);
  3757.         EndPutM16Inc(data, 0x201F | j << 9);    /* MOVE.L offs(A7),Dx */
  3758.       }
  3759.     }
  3760.   }
  3761.  
  3762.   return data;
  3763. }
  3764. /* ------------------------------------------------------------------ */
  3765.  
  3766. static void DoError(uint32 errnum, uint32 line, ...)
  3767. {
  3768.   uint32 err = errnum & 0xFFFF;
  3769.   va_list a;
  3770.  
  3771.   if(Flags & FLAG_DIDERROR)
  3772.     return;
  3773.  
  3774.   if(!Errors[err].Type)
  3775.     Flags |= FLAG_DIDERROR;
  3776.  
  3777.   va_start(a, line);
  3778.   printf((line ? "%s %ld in line %ld%s: " : "%s %ld : "), (uint32)
  3779.   (Errors[err].Type ? "Warning" : "Error"), err, line,
  3780.   errnum & ERROFFSET_CLIB ? " of clib file" : "");
  3781.   vprintf(Errors[err].Error, a);
  3782.   printf("\n");
  3783.   if(line && Errors[err].Skip)
  3784.   {
  3785.     while(*in.pos)
  3786.       ++in.pos;
  3787.   }
  3788.   va_end(a);
  3789. }
  3790.  
  3791. static uint32 CheckError(struct AmiPragma *ap, uint32 errflags)
  3792. {
  3793.   errflags &= ap->Flags;
  3794.  
  3795.   if(errflags & AMIPRAGFLAG_ARGCOUNT)
  3796.   {
  3797.     if(!(ap->Flags & AMIPRAGFLAG_DIDARGWARN))
  3798.     {
  3799.       DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER, ap->Line);
  3800.       ap->Flags |= AMIPRAGFLAG_DIDARGWARN;
  3801.     }
  3802.     return 1;
  3803.   }
  3804.   else if(errflags & AMIPRAGFLAG_FLOATARG)
  3805.   {
  3806.     if(!(ap->Flags & AMIPRAGFLAG_DIDFLOATWARN))
  3807.     {
  3808.       DoError(ERR_FLOATARG_NOT_ALLOWED, ap->Line);
  3809.       ap->Flags |= AMIPRAGFLAG_DIDFLOATWARN;
  3810.     }
  3811.     return 1;
  3812.   }
  3813.   else if(errflags & AMIPRAGFLAG_A6USE)
  3814.   {
  3815.     DoError(ERR_A6_NOT_ALLOWED, ap->Line);
  3816.     return 1;
  3817.   }
  3818.   else if(errflags & AMIPRAGFLAG_A5USE)
  3819.   {
  3820.     DoError(ERR_A5_NOT_ALLOWED, ap->Line);
  3821.     return 1;
  3822.   }
  3823.   else if(errflags & AMIPRAGFLAG_PPC)
  3824.   {
  3825.     if(!(Flags & FLAG_DIDPPCWARN))
  3826.     {
  3827.       DoError(ERR_PPC_FUNCTION_NOT_SUPPORTED, 0/*ap->Line*/);
  3828.       Flags |= FLAG_DIDPPCWARN;
  3829.     }
  3830.     return 1;
  3831.   }
  3832.   else if(errflags & AMIPRAGFLAG_M68K)
  3833.   {
  3834.     if(!(Flags & FLAG_DIDM68KWARN))
  3835.     {
  3836.       DoError(ERR_M68K_FUNCTION_NOT_SUPPORTED, 0/*ap->Line*/);
  3837.       Flags |= FLAG_DIDM68KWARN;
  3838.     }
  3839.     return 1;
  3840.   }
  3841.  
  3842.   return 0;
  3843. }
  3844.  
  3845. static uint32 DoOutput(strptr format, ...)
  3846. {
  3847.   va_list a;
  3848.  
  3849.   if(!Output_Error)
  3850.     return 0;
  3851.  
  3852.   va_start(a, format);
  3853.   if(vfprintf(outfile, format, a) < 0)
  3854.     Output_Error = 1;
  3855.   va_end(a);
  3856.  
  3857.   return Output_Error;
  3858. }
  3859.  
  3860. static uint32 DoOutputDirect(void * data, size_t size)
  3861. {
  3862.   if(!Output_Error)
  3863.     return 0;
  3864.   if(size)
  3865.   {
  3866.     if(fwrite(data, size, 1, outfile) != 1)
  3867.       Output_Error = 0;
  3868.   }
  3869.   return Output_Error;
  3870. }
  3871.  
  3872. /* ------------------------------------------------------------------ */
  3873.  
  3874. static struct ShortList *NewItem(struct ShortListRoot *list)
  3875. {
  3876.   struct ShortList *item;
  3877.   if(!list || !list->Size)
  3878.     return 0;
  3879.   if(!(item = (struct ShortList *) AllocListMem(list->Size)))
  3880.     return 0;
  3881.   return item;
  3882. }
  3883.  
  3884. static struct ShortList *RemoveItem(struct ShortListRoot *list,
  3885. struct ShortList *item)
  3886. {
  3887.   struct ShortList *n = list->First;
  3888.  
  3889.   if(n == item)
  3890.     list->First = item->Next;
  3891.   else
  3892.   {
  3893.     while(n && n->Next != item)
  3894.       n = n->Next;
  3895.     if(!n)
  3896.       return 0;
  3897.     if(!(n->Next = item->Next))
  3898.       list->Last = n;
  3899.   }
  3900.   item->Next = 0;
  3901.   return item;
  3902. }
  3903.  
  3904. static void AddItem(struct ShortListRoot *list, struct ShortList *item)
  3905. {
  3906.   if(!list->First)
  3907.     list->First = list->Last = item;
  3908.   else
  3909.   {
  3910.     list->Last->Next = item;
  3911.     list->Last = item;
  3912.   }
  3913. }
  3914.  
  3915. /* ------------------------------------------------------------------ */
  3916.  
  3917. uint32 FuncAMICALL(struct AmiPragma *ap, uint32 flags, strptr name)
  3918. {
  3919.   uint32 i;
  3920.  
  3921.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
  3922.     return 1;
  3923.  
  3924.   Flags |= FLAG_DONE; /* We did something */
  3925.  
  3926.   DoOutput("#pragma %s(%s,0x%03x,%s("/*))*/, flags & FUNCFLAG_TAG ?
  3927.   "tagcall" : "amicall", BaseName, ap->Bias, name);
  3928.  
  3929.   for(i = 0; i < ap->NumArgs; ++i)
  3930.   {
  3931.     DoOutput(RegNames[ap->Args[i].ArgReg]);
  3932.     if(i+1 < ap->NumArgs)
  3933.       DoOutput(",");
  3934.   }
  3935.  
  3936.   return DoOutput(/*((*/"))\n");
  3937. }
  3938.  
  3939. uint32 FuncLIBCALL(struct AmiPragma *ap, uint32 flags, strptr name)
  3940. {
  3941.   int32 i;
  3942.  
  3943.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
  3944.     return 1;
  3945.  
  3946.   Flags |= FLAG_DONE; /* We did something */
  3947.  
  3948.   if(ap->Flags & AMIPRAGFLAG_FLOATARG)
  3949.   {
  3950.     DoOutput("#pragma flibcall %s %-22s %03x ", BaseName, name, ap->Bias);
  3951.     for(i = ap->NumArgs-1; i >= 0; --i)
  3952.       DoOutput("%02x", ap->Args[i].ArgReg);
  3953.  
  3954.     return DoOutput("00%02x\n", ap->NumArgs);
  3955.   }
  3956.  
  3957.   if((Flags & FLAG_SYSCALL) && !strcmp(BaseName,"SysBase") &&
  3958.   (flags & FUNCFLAG_NORMAL))
  3959.     DoOutput("#pragma  syscall %-22s %03x ", name, ap->Bias);
  3960.   else
  3961.     DoOutput("#pragma  %s %s %-22s %03x ", (flags & FUNCFLAG_TAG) ?
  3962.     "tagcall" : "libcall", BaseName, name, ap->Bias);
  3963.  
  3964.   for(i = ap->NumArgs-1; i >= 0; --i)
  3965.     DoOutput("%x", ap->Args[i].ArgReg);
  3966.  
  3967.   return DoOutput("0%x\n", ap->NumArgs);
  3968. }
  3969.  
  3970. uint32 FuncAsmText(struct AmiPragma *ap, uint32 flags, strptr name)
  3971. {
  3972.   int32 i;
  3973.   uint32 registers;
  3974.   uint16 fregs;
  3975.   uint32 offset = 1;
  3976.   strptr c1, c2;
  3977.   struct ClibData *cd;
  3978.  
  3979.   if(CheckError(ap, AMIPRAGFLAG_PPC))
  3980.     return 1;
  3981.  
  3982.   Flags |= FLAG_DONE; /* We did something */
  3983.  
  3984.   c1 = Flags & FLAG_NEWSYNTAX ? "(" : ""; /*)*/
  3985.   c2 = Flags & FLAG_NEWSYNTAX ? "," : "("; /*)*/
  3986.  
  3987.   if(Flags & FLAG_SINGLEFILE)
  3988.   {
  3989.     if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
  3990.  
  3991.     if(HEADER)
  3992.     {
  3993.       DoOutput("\n");
  3994.       DoOutputDirect(HEADER, headersize);
  3995.     }
  3996.   }
  3997.  
  3998.   if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
  3999.   {
  4000.     DoOutput("\n\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname,
  4001.     Flags & FLAG_SMALLDATA ? "N" : "X", BaseName);
  4002.   }
  4003.  
  4004.   DoOutput("\n\tXDEF\t_%s\n_%s:\n",name, name);
  4005.   if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
  4006.   {
  4007.     DoOutput("\tXDEF\t%s\n%s:\n",name, name);
  4008.     if(clibdata)
  4009.     {
  4010.       if(!ap->NumArgs)
  4011.         DoOutput("\tXDEF\t%s_\n%s_:\n",name, name);
  4012.       else if((cd = GetClibFunc(name, ap, flags)))
  4013.       {
  4014.         string txt[300];
  4015.         uint32 i;
  4016.  
  4017.         for(i = 0; i < COPYCPP_PASSES; ++i)
  4018.         {
  4019.           if(CopyCPPType(txt, i, cd, ap->Args))
  4020.             DoOutput("\tXDEF\t%s__%s\n%s__%s:\n", name, txt, name, txt);
  4021.         }
  4022.       }
  4023.     }
  4024.   }
  4025.  
  4026.   if((registers = GetRegisterData(ap) >> 16))
  4027.   {
  4028.     if(Flags & FLAG_NOMOVEM)
  4029.     {
  4030.       for(i = 0; i <= 15; ++i)
  4031.       {
  4032.         if(registers & (1 << i))
  4033.         {
  4034.           ++offset;
  4035.           DoOutput("\tMOVE.L\t%s,-(A7)\n", RegNamesUpper[i]);
  4036.         }
  4037.       }
  4038.     }
  4039.     else
  4040.     {
  4041.       uint16 l = registers;
  4042.  
  4043.       DoOutput("\tMOVEM.L\t");
  4044.  
  4045.       for(i = 0; i <= 15; ++i)
  4046.       {
  4047.         if(l & (1 << i))
  4048.         {
  4049.           ++offset;
  4050.           l ^= 1 << i;
  4051.           DoOutput(RegNamesUpper[i]);
  4052.           if(l)
  4053.             DoOutput("/");
  4054.         }
  4055.       }
  4056.       DoOutput(",-(A7)\n");
  4057.     }
  4058.   }
  4059.   else
  4060.   {
  4061.     DoOutput("\tMOVE.L\tA6,-(A7)\n"); ++offset;
  4062.   }
  4063.  
  4064.   if((fregs = GetFRegisterData(ap) >> 8))
  4065.   {
  4066.     uint8 l = fregs;
  4067.  
  4068.     DoOutput("\tFMOVEM.X\t");
  4069.  
  4070.     for(i = 0; i <= 7; ++i)
  4071.     {
  4072.       if(l & (1 << i))
  4073.       {
  4074.         offset += 3;
  4075.         l ^= 1 << i;
  4076.         DoOutput(RegNamesUpper[REG_FP0 + i]);
  4077.         if(l)
  4078.           DoOutput("/");
  4079.       }
  4080.     }
  4081.     DoOutput(",-(A7)\n");
  4082.   }
  4083.  
  4084.   if(Flags & FLAG_SMALLDATA)
  4085.   {
  4086.     DoOutput(/*(*/"\tMOVEA.L\t%s_%s%sA4),A6\n", c1, BaseName, c2);
  4087.   }
  4088.   else
  4089.     DoOutput("\tMOVEA.L\t_%s,A6\n", BaseName);
  4090.  
  4091.   if(!(Flags & FLAG_PASCAL))
  4092.   {
  4093.     int32 k;
  4094.  
  4095.     k = ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0);
  4096.  
  4097.     for(i = 0; i < k;)
  4098.     {
  4099.       if(ap->Args[i].ArgReg >= REG_FP0)
  4100.       {
  4101.         uint32 t;
  4102.         struct ClibData *cd;
  4103.  
  4104.         cd = GetClibFunc(name, ap, flags);
  4105.         if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_DOUBLE))
  4106.           t = CPP_TYPE_DOUBLE;
  4107.         else if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_FLOAT))
  4108.           t = CPP_TYPE_FLOAT;
  4109.         else
  4110.         {
  4111.           DoError(ERR_LONG_DOUBLE, ap->Line);
  4112.           t = CPP_TYPE_FLOAT;
  4113.         }
  4114.  
  4115.         DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t == CPP_TYPE_DOUBLE ? 'D' : 'S', c1,
  4116.         offset<<2, c2, RegNamesUpper[ap->Args[i++].ArgReg]);
  4117.  
  4118.         if(t == CPP_TYPE_DOUBLE)
  4119.           ++offset;
  4120.         ++offset;
  4121.       }
  4122.       else if(((k - i) >= 2) && (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg) &&
  4123.       ap->Args[i+1].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
  4124.       {
  4125.         DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1, (offset++)<<2, c2,
  4126.         RegNamesUpper[ap->Args[i++].ArgReg]);
  4127.  
  4128.         do
  4129.         {
  4130.           DoOutput("/%s", RegNamesUpper[ap->Args[i++].ArgReg]);
  4131.           ++offset;
  4132.         } while((i < k) && (ap->Args[i-1].ArgReg < ap->Args[i].ArgReg) &&
  4133.         ap->Args[i].ArgReg < REG_FP0);
  4134.         DoOutput("\n");
  4135.       }
  4136.       else
  4137.       {
  4138.         DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
  4139.         ap->Args[i].ArgReg >= REG_A0 ? "A" : "", c1, (offset++)<<2, c2,
  4140.         RegNamesUpper[ap->Args[i].ArgReg]);
  4141.         ++i;
  4142.       }
  4143.     }
  4144.  
  4145.     if(i < ap->NumArgs)
  4146.     {
  4147.       if(ap->Args[i].ArgReg > 7)
  4148.         DoOutput(/*(*/"\tLEA\t%s%02ld%sA7),%s\n", c1, offset<<2, c2,
  4149.         RegNamesUpper[ap->Args[i].ArgReg]);
  4150.       else if(offset <= 2)
  4151.         DoOutput("\tMOVE.L\tA7,%s\n\tADDQ.L\t#%02ld,%s\n",
  4152.         RegNamesUpper[ap->Args[i].ArgReg],offset<<2,
  4153.         RegNamesUpper[ap->Args[i].ArgReg]);
  4154.       else
  4155.         DoOutput(/*(*/"\tPEA\t%s%ld%sA7)\n\tMOVE.L\t(A7)+,%s\n",c1,
  4156.         offset<<2, c2,RegNamesUpper[ap->Args[i].ArgReg]);
  4157.     }
  4158.   }
  4159.   else
  4160.   {
  4161.     i = ap->NumArgs;
  4162.  
  4163.     while(i)
  4164.     {
  4165.       if(ap->Args[i-1].ArgReg >= REG_FP0)
  4166.       {
  4167.         uint32 t;
  4168.         struct ClibData *cd;
  4169.  
  4170.         cd = GetClibFunc(name, ap, flags);
  4171.  
  4172.         if(cd && IsCPPType(&cd->Args[i-1], CPP_TYPE_DOUBLE))
  4173.           t = CPP_TYPE_DOUBLE;
  4174.         else if(cd && IsCPPType(&cd->Args[i-1], CPP_TYPE_FLOAT))
  4175.           t = CPP_TYPE_FLOAT;
  4176.         else
  4177.         {
  4178.           DoError(ERR_LONG_DOUBLE, ap->Line);
  4179.           t = CPP_TYPE_FLOAT;
  4180.         }
  4181.  
  4182.         DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t == CPP_TYPE_DOUBLE ? 'D' : 'S',
  4183.         c1, offset<<2, c2, RegNamesUpper[ap->Args[--i].ArgReg]);
  4184.         if(t == CPP_TYPE_DOUBLE)
  4185.           ++offset;
  4186.         ++offset;
  4187.       }
  4188.       else if((i >= 2) && (ap->Args[i-1].ArgReg < ap->Args[i-2].ArgReg) &&
  4189.       ap->Args[i-2].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
  4190.       {
  4191.         DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1, (offset++)<<2, c2,
  4192.         RegNamesUpper[ap->Args[--i].ArgReg]);
  4193.  
  4194.         do
  4195.         {
  4196.           DoOutput("/%s", RegNamesUpper[ap->Args[--i].ArgReg]);
  4197.           ++offset;
  4198.         } while(i && (ap->Args[i].ArgReg < ap->Args[i-1].ArgReg) &&
  4199.         ap->Args[i-1].ArgReg < REG_FP0);
  4200.         DoOutput("\n");
  4201.       }
  4202.       else
  4203.       {
  4204.         --i;
  4205.         DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
  4206.         ap->Args[i].ArgReg >= REG_A0 ? "A" : "", c1, (offset++)<<2, c2,
  4207.         RegNamesUpper[ap->Args[i].ArgReg]);
  4208.       }
  4209.     }
  4210.   }
  4211.  
  4212.   DoOutput(/*(*/"\tJSR\t%s-%03d%sA6)\n", c1, ap->Bias, c2);
  4213.  
  4214.   if(fregs)
  4215.   {
  4216.     DoOutput("\tFMOVEM.X\t(A7)+,");
  4217.  
  4218.     for(i = 0; i <= 7; ++i)
  4219.     {
  4220.       if(fregs & (1 << i))
  4221.       {
  4222.         fregs ^= 1 << i;
  4223.         DoOutput(RegNamesUpper[REG_FP0 + i]);
  4224.         if(fregs)
  4225.           DoOutput("/");
  4226.       }
  4227.     }
  4228.     DoOutput("\n");
  4229.   }
  4230.  
  4231.   if(registers)
  4232.   {
  4233.     if(Flags & FLAG_NOMOVEM)
  4234.     {
  4235.       for(i = 15; i >= 0; --i)
  4236.       {
  4237.         if(registers & (1 << i))
  4238.           DoOutput("\tMOVE%s.L\t(A7)+,%s\n", i >= REG_A0 ? "A" : "", RegNamesUpper[i]);
  4239.       }
  4240.     }
  4241.     else
  4242.     {
  4243.       DoOutput("\tMOVEM.L\t(A7)+,");
  4244.  
  4245.       for(i = 0; i <= 15; ++i)
  4246.       {
  4247.         if(registers & (1 << i))
  4248.         {
  4249.           registers ^= 1 << i;
  4250.           DoOutput(RegNamesUpper[i]);
  4251.           if(registers)
  4252.             DoOutput("/");
  4253.         }
  4254.       }
  4255.       DoOutput("\n");
  4256.     }
  4257.   }
  4258.   else
  4259.     DoOutput("\tMOVEA.L\t(A7)+,A6\n");
  4260.  
  4261.   return DoOutput("\tRTS\n");
  4262. }
  4263.  
  4264. uint32 FuncAsmCode(struct AmiPragma *ap, uint32 flags, strptr name)
  4265. {
  4266.   uint32 registers, offset = 1, baseref;
  4267.   size_t i;
  4268.   uint8 *data;
  4269.   uint16 fregs;
  4270.  
  4271.   if(CheckError(ap, AMIPRAGFLAG_PPC))
  4272.     return 1;
  4273.  
  4274.   Flags |= FLAG_DONE; /* We did something */
  4275.  
  4276.   registers = GetRegisterData(ap);
  4277.   fregs = GetFRegisterData(ap);
  4278.  
  4279.   i = strlen(name);
  4280.   EndPutM32(tempbuf, HUNK_UNIT);
  4281.   EndPutM32(tempbuf+4, (i+3)>>2);
  4282.   DoOutputDirect(tempbuf, 8);
  4283.   DoOutputDirect(name, i);
  4284.   DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
  4285.  
  4286.   i = strlen(hunkname);
  4287.   EndPutM32(tempbuf, HUNK_NAME);
  4288.   EndPutM32(tempbuf+4, (i + 3)>>2);
  4289.   DoOutputDirect(tempbuf, 8);
  4290.   DoOutputDirect(hunkname, i);
  4291.   DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
  4292.  
  4293.   data = tempbuf+8; /* we need HUNK_CODE + size at start */
  4294.  
  4295.   if(!registers)
  4296.   {
  4297.     EndPutM16Inc(data, 0x2F0E);                 /* MOVE.L A6,-(A7) */
  4298.     ++offset;                                   /* one long more on stack */
  4299.   }
  4300.   else
  4301.   {
  4302.     if(Flags & FLAG_NOMOVEM)
  4303.     {
  4304.       for(i = 0; i <= 15; ++i)
  4305.       {
  4306.         if(registers & (1<< (16+i)))
  4307.         {
  4308.           EndPutM16Inc(data, 0x2F00 + i);       /* MOVE.L xxx,-(A7) */
  4309.           ++offset;
  4310.         }
  4311.       }
  4312.     }
  4313.     else
  4314.     {
  4315.       uint32 l;
  4316.       EndPutM16Inc(data, 0x48E7);               /* MOVEM.L xxx,-(A7) */
  4317.       EndPutM16Inc(data, registers);            /* store MOVEM.L registers */
  4318.       for(l = (uint16) registers; l; l >>= 1)
  4319.       {
  4320.         if(l & 1)
  4321.           ++offset;                             /* get offset addition */
  4322.       }
  4323.     }
  4324.   }
  4325.  
  4326.   if(fregs)
  4327.   {
  4328.     uint32 l;
  4329.     EndPutM16Inc(data, 0xF227);                 /* FMOVEM.X xxx,-(A7) */
  4330.     EndPutM16Inc(data, 0xE000 + ((fregs>>8)&0xFF));
  4331.     for(l = (uint8) fregs; l; l >>= 1)
  4332.     {
  4333.       if(l & 1)
  4334.         offset+=3;                              /* get offset addition */
  4335.     }
  4336.   }
  4337.  
  4338.   baseref = (data-tempbuf)-8+2;                 /* one word later (MOVE) - 2 header longs */
  4339.   if(Flags & FLAG_SMALLDATA)
  4340.   {
  4341.     EndPutM16Inc(data, 0x2C6C);                 /* MOVEA.L base(A4),A6 */
  4342.     EndPutM16Inc(data, 0);                      /* place for base reference */
  4343.   }
  4344.   else
  4345.   {
  4346.     EndPutM16Inc(data, 0x2C79);                 /* MOVEA.L base,A6 */
  4347.     EndPutM32Inc(data, 0);                      /* place for base reference */
  4348.   }
  4349.  
  4350.   data = AsmStackCopy(data, ap, flags, offset);
  4351.  
  4352.   /* here comes the base reference */
  4353.   EndPutM16Inc(data, 0x4EAE);                   /* JSR xxx(A6) */
  4354.   EndPutM16Inc(data, -ap->Bias);                /* JSR offset */
  4355.  
  4356.   if(fregs)
  4357.   {
  4358.     EndPutM16Inc(data, 0xF21F);                 /* FMOVEM.X (A7)+,xxx */
  4359.     EndPutM16Inc(data, 0xD000 + (fregs&0xFF));
  4360.   }
  4361.  
  4362.   if(registers)
  4363.   {
  4364.     if(Flags & FLAG_NOMOVEM)
  4365.     {
  4366.       int32 i;
  4367.       for(i = 15; i >= 0; --i)
  4368.       {
  4369.         if(registers & (1<<(16+i)))             /* MOVE.L (A7)+,xxx */
  4370.           EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6));
  4371.       }
  4372.     }
  4373.     else
  4374.     {
  4375.       EndPutM16Inc(data, 0x4CDF);               /* MOVEM.L (A7)+,xxx */
  4376.       EndPutM16Inc(data, (registers >> 16));    /* store MOVEM.L registers */
  4377.     }
  4378.   }
  4379.   else
  4380.     EndPutM16Inc(data, 0x2C5F);                 /* MOVE.L (A7)+,A6 */
  4381.   EndPutM16Inc(data, 0x4E75);                   /* RTS */
  4382.  
  4383.   EndPutM16Inc(data, 0);                        /* get longword assignment if not yet */
  4384.  
  4385.   EndPutM32(tempbuf, HUNK_CODE);
  4386.   EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
  4387.   DoOutputDirect(tempbuf, (size_t)(data-tempbuf)&(~3));
  4388.  
  4389.   EndPutM32(tempbuf, HUNK_EXT);
  4390.   DoOutputDirect(tempbuf, 4);
  4391.  
  4392.   OutputXREF(baseref, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "_%s", BaseName);
  4393.   /* here come the XDEF name references */
  4394.   OutputXDEF(0, "_%s", name);                      /* C name */
  4395.  
  4396.   if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
  4397.   {
  4398.     struct ClibData *cd;
  4399.     OutputXDEF(0, "%s", name);                     /* ASM name */
  4400.  
  4401.     if(clibdata)
  4402.     {
  4403.       if(!ap->NumArgs)
  4404.         OutputXDEF(0, "%s_", name);                /* C++ name no parameters */
  4405.       else if((cd = GetClibFunc(name, ap, flags)))
  4406.       {
  4407.         for(i = 0; i < COPYCPP_PASSES; ++i) /* C++ name with parameters */
  4408.         {
  4409.           if(CopyCPPType((strptr)tempbuf, i, cd, ap->Args))
  4410.             OutputXDEF(0, "%s__%s", name, tempbuf);
  4411.         }
  4412.       }
  4413.     }
  4414.   }
  4415.  
  4416.   EndPutM32(tempbuf, 0);
  4417.   DoOutputDirect(tempbuf, 4);
  4418.   if(!(Flags & FLAG_NOSYMBOL))
  4419.   {
  4420.     EndPutM32(tempbuf, HUNK_SYMBOL);
  4421.     DoOutputDirect(tempbuf, 4);
  4422.     OutputSYMBOL(0, "_%s", name);              /* C name */
  4423.  
  4424.     if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
  4425.     {
  4426.       struct ClibData *cd;
  4427.       OutputSYMBOL(0, "%s", name);             /* ASM name */
  4428.  
  4429.       if(clibdata)
  4430.       {
  4431.         if(!ap->NumArgs)
  4432.           OutputSYMBOL(0, "%s_", name);        /* C++ name no parameters */
  4433.         else if((cd = GetClibFunc(name, ap, flags)))
  4434.         {
  4435.           for(i = 0; i < COPYCPP_PASSES; ++i) /* C++ name with parameters */
  4436.           {
  4437.             if(CopyCPPType((strptr) data, i, cd, ap->Args))
  4438.               OutputSYMBOL(0, "%s__%s", name, (strptr) data);
  4439.           }
  4440.         }
  4441.       }
  4442.     }
  4443.  
  4444.     EndPutM32(tempbuf, 0);
  4445.     DoOutputDirect(tempbuf, 4);
  4446.   }
  4447.  
  4448.   EndPutM32(tempbuf, HUNK_END);
  4449.   return DoOutputDirect(tempbuf, 4);
  4450. }
  4451.  
  4452. /* Directly called by FuncInline and FuncInlineDirect also! */
  4453. uint32 FuncCSTUBS(struct AmiPragma *ap, uint32 flags, strptr name)
  4454. {
  4455.   struct ClibData *f, *t;
  4456.   strptr ret = "return ";
  4457.   int32 i;
  4458.  
  4459.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
  4460.     return 1;
  4461.  
  4462.   Flags |= FLAG_DONE; /* We did something */
  4463.  
  4464.   if(!(f = GetClibFunc(ap->FuncName, ap, 0)))
  4465.     return 1;
  4466.   t = GetClibFunc(name, ap, flags);
  4467.  
  4468.   if(flags & FUNCFLAG_EXTENDMODE)
  4469.   {
  4470.     sprintf(tempbuf, "___%s", name);
  4471.     name = tempbuf;
  4472.   }
  4473.  
  4474.   if(IsCPPType(&f->ReturnType, CPP_TYPE_VOID))
  4475.     ret = "";
  4476.  
  4477.   if(!OutClibType(&f->ReturnType, name) || !DoOutput("("/*)*/))
  4478.     return 0;
  4479.   if(flags & FUNCFLAG_EXTENDMODE)
  4480.   {
  4481.     DoOutput("%s %s, ", GetBaseType(), BaseName);
  4482.   }
  4483.  
  4484.   for(i = 0; i < ap->NumArgs-1; i++)
  4485.   {
  4486.     if(!OutClibType(&f->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
  4487.       return 0;
  4488.   }
  4489.   if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
  4490.   {
  4491.     if(!OutClibType(&t->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
  4492.       return 0;
  4493.   }
  4494.   else if(ap->NumArgs == 1 && !DoOutput("ULONG tag, "))
  4495.     return 0;
  4496.  
  4497.   if(!DoOutput(/*(*/"...)\n{\n  %s%s("/*)*/, ret, ap->FuncName))
  4498.     return 0;
  4499.   for(i = 0; i < ap->NumArgs-1; i++)
  4500.   {
  4501.     if(!DoOutput("%s, ", ap->Args[i].ArgName))
  4502.       return 0;
  4503.   }
  4504.   if(!DoOutput("("/*)*/) || !OutClibType(&f->Args[ap->NumArgs-1],0))
  4505.     return 0;
  4506.  
  4507.   if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
  4508.   {
  4509.     if(!DoOutput(/*((*/") &%s);\n}\n\n", ap->Args[ap->NumArgs-1].ArgName))
  4510.       return 0;
  4511.   }
  4512.   else if(ap->NumArgs == 1)
  4513.   {
  4514.     if(!DoOutput(/*((*/") &tag);\n}\n\n"))
  4515.       return 0;
  4516.   }
  4517.   else if (!DoOutput(/*(*/") ((ULONG) &%s + sizeof("/*))*/,
  4518.   ap->Args[ap->NumArgs-2].ArgName) || !OutClibType(&f->Args[ap->NumArgs-2],0)
  4519.   || !DoOutput(/*(((*/")));\n}\n\n"))
  4520.     return 0;
  4521.   return 1;
  4522. }
  4523.  
  4524. uint32 FuncLVOXDEF(struct AmiPragma *ap, uint32 flags, strptr name)
  4525. {
  4526.   Flags |= FLAG_DONE; /* We did something */
  4527.   return DoOutput("\t\tXDEF\t_LVO%s\n", name);
  4528. }
  4529.  
  4530. uint32 FuncLVO(struct AmiPragma *ap, uint32 flags, strptr name)
  4531. {
  4532.   Flags |= FLAG_DONE; /* We did something */
  4533.   return DoOutput("\n_LVO%-24s\tEQU\t-%d", name, ap->Bias);
  4534. }
  4535.  
  4536. uint32 FuncLVOPPCXDEF(struct AmiPragma *ap, uint32 flags, strptr name)
  4537. {
  4538.   Flags |= FLAG_DONE; /* We did something */
  4539.   return DoOutput("\t.globl\t%sLVO%s\n", Flags & FLAG_ABIV4 ? "" : "_", name);
  4540. }
  4541.  
  4542. uint32 FuncLVOPPC(struct AmiPragma *ap, uint32 flags, strptr name)
  4543. {
  4544.   Flags |= FLAG_DONE; /* We did something */
  4545.   return DoOutput(".set\t%sLVO%s,-%d\n", Flags & FLAG_ABIV4 ? "" : "_", name, ap->Bias);
  4546. }
  4547.  
  4548. uint32 FuncLVOPPCBias(struct AmiPragma *ap, uint32 flags, strptr name)
  4549. {
  4550.   Flags |= FLAG_DONE; /* We did something */
  4551.  
  4552.   EndPutM32Inc(elfbufpos, symoffset);                    /* st_name */
  4553.   symoffset += strlen(name) + 3 + (Flags & FLAG_ABIV4 ? 0 : 1) + 1;
  4554.   EndPutM32Inc(elfbufpos, -ap->Bias);                    /* st_value */
  4555.   EndPutM32Inc(elfbufpos, 0);                            /* st_size */
  4556.   *(elfbufpos++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* st_info */
  4557.   *(elfbufpos++) = 0;                                    /* st_other */
  4558.   EndPutM16Inc(elfbufpos, SHN_ABS);                      /* st_shndx */
  4559.  
  4560.   return 1;
  4561. }
  4562.  
  4563. uint32 FuncLVOPPCName(struct AmiPragma *ap, uint32 flags, strptr name)
  4564. {
  4565.   Flags |= FLAG_DONE; /* We did something */
  4566.   DoOutput("%sLVO%s", Flags & FLAG_ABIV4 ? "" : "_", name);
  4567.   return DoOutputDirect("", 1);
  4568. }
  4569.  
  4570. uint32 FuncLVOLib(struct AmiPragma *ap, uint32 flags, strptr name)
  4571. {
  4572.   uint32 j;
  4573.  
  4574.   Flags |= FLAG_DONE; /* We did something */
  4575.   j = strlen(name) + 3 + (Flags & FLAG_ABIV4 ? 0 : 1);
  4576.   EndPutM32(tempbuf, (EXT_ABS << 24) + ((j+3)>>2));
  4577.  
  4578.   DoOutputDirect(tempbuf, 4);
  4579.   DoOutput("%sLVO%s", Flags & FLAG_ABIV4 ? "" : "_", name);
  4580.   DoOutputDirect("\0\0\0", ((j+3)&(~3))-j);
  4581.   EndPutM32(tempbuf, -ap->Bias);
  4582.   return DoOutputDirect(tempbuf, 4);
  4583. }
  4584.  
  4585. uint32 FuncLocCode(struct AmiPragma *ap, uint32 flags, strptr name)
  4586. {
  4587.   strptr str2 = Flags & FLAG_LOCALREG ? "rE" : "";
  4588.   uint8 *data;
  4589.   int32 i;
  4590.   struct ClibData *cd = 0;
  4591.  
  4592.   if(CheckError(ap, AMIPRAGFLAG_PPC))
  4593.     return 1;
  4594.  
  4595.   Flags |= FLAG_DONE; /* We did something */
  4596.  
  4597.   i = strlen(name);
  4598.   EndPutM32(tempbuf, HUNK_UNIT);
  4599.   EndPutM32(tempbuf+4, (i+3)>>2);
  4600.   DoOutputDirect(tempbuf, 8);
  4601.   DoOutputDirect(name, i);
  4602.   DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
  4603.  
  4604.   i = strlen(hunkname);
  4605.   EndPutM32(tempbuf, HUNK_NAME);
  4606.   EndPutM32(tempbuf+4, (i + 3)>>2);
  4607.   DoOutputDirect(tempbuf, 8);
  4608.   DoOutputDirect(hunkname, i);
  4609.   DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
  4610.  
  4611.   data = tempbuf+8; /* we need HUNK_CODE + size at start */
  4612.  
  4613.   if(Flags & FLAG_LOCALREG)
  4614.   {
  4615.     if((flags & FUNCFLAG_TAG))
  4616.     {
  4617.       i = ap->Args[ap->NumArgs-1].ArgReg;
  4618.       EndPutM16Inc(data, 0x2F00 + i);                   /* MOVE <ea>,-(A7) */
  4619.  
  4620.       if(i > 7)
  4621.       {
  4622.         EndPutM16Inc(data, 0x41EF | ((i-8) << 9));      /* LEA 8(A7),Ax */
  4623.         EndPutM16Inc(data, 8);
  4624.       }
  4625.       else
  4626.       {
  4627.         EndPutM16Inc(data, 0x200F | (i << 9));          /* MOVE.L A7,Dx */
  4628.         EndPutM16Inc(data, 0x5080 | i);                 /* ADDQ.L #8,Dx */
  4629.       }
  4630.  
  4631.       EndPutM16Inc(data, 0x4EAE);
  4632.       EndPutM16Inc(data, -ap->Bias);                    /* JSR instruction */
  4633.  
  4634.       EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6)); /* MOVE (A7)+,<ea> */
  4635.       EndPutM16Inc(data, 0x4E75);                       /* RTS */
  4636.     }
  4637.     else
  4638.     {
  4639.       EndPutM16Inc(data, 0x4EEE);
  4640.       EndPutM16Inc(data, -ap->Bias);                    /* JMP instruction */
  4641.     }
  4642.   }
  4643.   else
  4644.   {
  4645.     uint32 registers, offset = 1;
  4646.  
  4647.     registers = GetRegisterData(ap);
  4648.  
  4649.     if(!registers) /* happens only when !(ap->Flags & AMIPRAG_A6USE) */
  4650.     {
  4651.       EndPutM16Inc(data, 0x2F0E);                       /* MOVE.L A6,-(A7) */
  4652.       ++offset;                                         /* one long more on stack */
  4653.     }
  4654.     else
  4655.     {
  4656.       if(Flags & FLAG_NOMOVEM)
  4657.       {
  4658.         for(i = 0; i <= 15; ++i)
  4659.         {
  4660.           if(registers & (1<< (16+i)))
  4661.           {
  4662.             EndPutM16Inc(data, 0x2F00 + i);             /* MOVE.L xxx,-(A7) */
  4663.             ++offset;
  4664.           }
  4665.         }
  4666.       }
  4667.       else
  4668.       {
  4669.         EndPutM16Inc(data, 0x48E7);                     /* MOVEM.L xxx,-(A7) */
  4670.         EndPutM16Inc(data, registers);                  /* store MOVEM.L registers */
  4671.         for(i = registers&0xFFFF; i; i >>= 1)
  4672.         {
  4673.           if(i & 1)
  4674.             ++offset;                                   /* get offset addition */
  4675.         }
  4676.       }
  4677.     }
  4678.  
  4679.     if(!(ap->Flags & AMIPRAGFLAG_A6USE)) /* store library base in A6 */
  4680.     {
  4681.       EndPutM16Inc(data, 0x2C6F);                       /* MOVE.L ofs(A7),A6 */
  4682.       EndPutM16Inc(data, (offset++) << 2);
  4683.     }
  4684.  
  4685.     data = AsmStackCopy(data, ap, flags, offset);
  4686.  
  4687.     /* here comes the base reference */
  4688.     EndPutM16Inc(data, 0x4EAE);                         /* JSR xxx(A6) */
  4689.     EndPutM16Inc(data, -ap->Bias);                      /* JSR offset */
  4690.     if(registers)
  4691.     {
  4692.       if(Flags & FLAG_NOMOVEM)
  4693.       {
  4694.         for(i = 15; i >= 0; --i)
  4695.         {
  4696.           if(registers & (1<<(16+i)))                   /* MOVE.L (A7)+,xxx */
  4697.             EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6));
  4698.         }
  4699.       }
  4700.       else
  4701.       {
  4702.         EndPutM16Inc(data, 0x4CDF);                     /* MOVEM.L (A7)+,xxx */
  4703.         EndPutM16Inc(data, registers >> 16);            /* store MOVEM.L registers */
  4704.       }
  4705.     }
  4706.     else
  4707.       EndPutM16Inc(data, 0x2C5F);                       /* MOVE.L (A7)+,A6 */
  4708.  
  4709.     EndPutM16Inc(data, 0x4E75);                         /* RTS */
  4710.   }
  4711.  
  4712.   EndPutM16Inc(data, 0);                                /* get longword assignment if not yet */
  4713.  
  4714.   EndPutM32(tempbuf, HUNK_CODE);
  4715.   EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
  4716.   DoOutputDirect(tempbuf, (data-tempbuf)&(~3));
  4717.  
  4718.   EndPutM32(tempbuf, HUNK_EXT);
  4719.   DoOutputDirect(tempbuf,4);
  4720.  
  4721.   /* here come the XDEF name references */
  4722.  
  4723.   if(!(Flags & FLAG_ONLYCNAMES))
  4724.   {
  4725.     OutputXDEF(0, "%s", name);             /* ASM names */
  4726.     OutputXDEF(0, "LOC_%s", name);
  4727.   }
  4728.  
  4729.   OutputXDEF(0, "_%s", name);              /* C names */
  4730.   OutputXDEF(0, "_LOC_%s", name);
  4731.  
  4732.   if(clibdata && !(Flags & FLAG_ONLYCNAMES))
  4733.   {
  4734.     if(!ap->NumArgs)
  4735.     {
  4736.       OutputXDEF(0, "%s__%sP07Library", name, str2); /* C++ names no parameters */
  4737.       OutputXDEF(0, "LOC_%s__%sP07Library", name, str2);
  4738.     }
  4739.     else if((cd = GetClibFunc(name, ap, flags)))
  4740.     {
  4741.       strptr txt;
  4742.  
  4743.       txt = (strptr) tempbuf;
  4744.   
  4745.       for(i = 0; i < COPYCPP_PASSES; ++i)
  4746.       {
  4747.         if(CopyCPPType(txt, i, cd, ap->Args))
  4748.         {                                 /* C++ names with parameters */
  4749.           if(!(ap->Flags & AMIPRAGFLAG_A6USE))
  4750.           {
  4751.             OutputXDEF(0, "%s__%sP07Library%s", name, str2, txt);
  4752.             OutputXDEF(0, "LOC_%s__%sP07Library%s", name, str2, txt);
  4753.           }
  4754.           else
  4755.           {
  4756.             OutputXDEF(0, "%s__%s", name, txt);
  4757.             OutputXDEF(0, "LOC_%s__%s", name, txt);
  4758.           }
  4759.         }
  4760.       }
  4761.     }
  4762.   }
  4763.  
  4764.   EndPutM32(tempbuf, 0);
  4765.   DoOutputDirect(tempbuf,4);
  4766.   if(!(Flags & FLAG_NOSYMBOL))
  4767.   {
  4768.     EndPutM32(tempbuf, HUNK_SYMBOL);
  4769.     DoOutputDirect(tempbuf,4);
  4770.     if(!(Flags & FLAG_ONLYCNAMES))
  4771.     {
  4772.       OutputSYMBOL(0, "%s", name);             /* ASM names */
  4773.       OutputSYMBOL(0, "LOC_%s", name);
  4774.     }
  4775.  
  4776.     OutputSYMBOL(0, "_%s", name);              /* C names */
  4777.     OutputSYMBOL(0, "_LOC_%s", name);
  4778.  
  4779.     if(clibdata && !(Flags & FLAG_ONLYCNAMES))
  4780.     {
  4781.       if(!ap->NumArgs)
  4782.       {
  4783.         OutputSYMBOL(0, "%s__%sP07Library", name, str2); /* C++ names no parameters */
  4784.         OutputSYMBOL(0, "LOC_%s__%sP07Library", name, str2);
  4785.       }
  4786.       else if(cd)
  4787.       {
  4788.         strptr txt;
  4789.  
  4790.         txt = (strptr) tempbuf;
  4791.   
  4792.         for(i = 0; i < COPYCPP_PASSES; ++i)
  4793.         {
  4794.           if(CopyCPPType(txt, i, cd, ap->Args))
  4795.           {                                 /* C++ names with parameters */
  4796.             if(!(ap->Flags & AMIPRAGFLAG_A6USE))
  4797.             {
  4798.               OutputSYMBOL(0, "%s__%sP07Library%s", name, str2, txt);
  4799.               OutputSYMBOL(0, "LOC_%s__%sP07Library%s", name, str2, txt);
  4800.             }
  4801.             else
  4802.             {
  4803.               OutputSYMBOL(0, "%s__%s", name, txt);
  4804.               OutputSYMBOL(0, "LOC_%s__%s", name, txt);
  4805.             }
  4806.           }
  4807.         }
  4808.       }
  4809.     }
  4810.  
  4811.     EndPutM32(tempbuf, 0);
  4812.     DoOutputDirect(tempbuf,4);
  4813.   }
  4814.   EndPutM32(tempbuf, HUNK_END);
  4815.   return DoOutputDirect(tempbuf,4);
  4816. }
  4817.  
  4818. uint32 FuncLocText(struct AmiPragma *ap, uint32 flags, strptr name)
  4819. {
  4820.   struct ClibData *cd;
  4821.   int32 i;
  4822.  
  4823.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
  4824.     return 1;
  4825.  
  4826.   Flags |= FLAG_DONE; /* We did something */
  4827.  
  4828.   if(!(cd = GetClibFunc(name, ap, flags)))
  4829.     return 1;
  4830.  
  4831.   OutClibType(&cd->ReturnType, 0);
  4832.   DoOutput(" LOC_%s("/*)*/, name);
  4833.   if(!(ap->Flags & AMIPRAGFLAG_A6USE))
  4834.   {
  4835.     if(Flags & FLAG_LOCALREG)
  4836.       DoOutput("register __a6 ");
  4837.     DoOutput("%s libbase", GetBaseType());
  4838.     if(ap->NumArgs)
  4839.       DoOutput(", ");
  4840.   }
  4841.  
  4842.   if(ap->NumArgs)
  4843.   {
  4844.     for(i = 0; i < ap->NumArgs-1; i++)
  4845.     {
  4846.       if(((Flags & FLAG_LOCALREG &&
  4847.       !DoOutput("register __%s ", RegNames[ap->Args[i].ArgReg]))) ||
  4848.       !OutClibType(&cd->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
  4849.         return 0;
  4850.     }
  4851.  
  4852.     if(flags & FUNCFLAG_NORMAL)
  4853.     {
  4854.       if(((Flags & FLAG_LOCALREG &&
  4855.       !DoOutput("register __%s ", RegNames[ap->Args[i].ArgReg]))) ||
  4856.       !OutClibType(&cd->Args[i], ap->Args[i].ArgName) ||
  4857.       !DoOutput(/*(*/");\n"))
  4858.         return 0;
  4859.       if(BaseName)
  4860.       {
  4861.         DoOutput("#define %s("/*)*/, name);
  4862.         for(i = 0; i < ap->NumArgs-1; ++i)
  4863.           DoOutput("%c, ", 'a'+(char)i);
  4864.         DoOutput(/*(*/"%c) LOC_%s(%s, "/*)*/,'a'+(char)i, name, BaseName);
  4865.         for(i = 0; i < ap->NumArgs-1; ++i)
  4866.           DoOutput("%c, ",'a'+(char)i);
  4867.         return DoOutput(/*(*/"%c)\n\n",'a'+(char)i);
  4868.       }
  4869.     }
  4870.     else
  4871.       return DoOutput(/*(*/"...);\n");
  4872.   }
  4873.   else if(BaseName)
  4874.     return DoOutput(/*(*/");\n#define %s(a) LOC_%s(a)\n\n",
  4875.     name, name);
  4876.   else
  4877.     return DoOutput(/*(*/");\n");
  4878.   return 1;
  4879. }
  4880.  
  4881. uint32 FuncInlineDirect(struct AmiPragma *ap, uint32 flags, strptr name)
  4882. {
  4883.   uint32 a4 = 0, a5 = 0;
  4884.   int32 noret = 0;
  4885.   int32 i;
  4886.   struct ClibData *cd;
  4887.  
  4888.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
  4889.     return 1;
  4890.  
  4891.   Flags |= FLAG_DONE; /* We did something */
  4892.  
  4893.   if(flags & FUNCFLAG_ALIAS)
  4894.   {
  4895.     if(flags & FUNCFLAG_TAG)
  4896.       return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
  4897.       name, ap->TagName);
  4898.  
  4899.     DoOutput("#define %s("/*)*/, name);
  4900.     for(i = 0; i < ap->NumArgs-1; ++i)
  4901.       DoOutput("%s, ", ap->Args[i].ArgName);
  4902.     DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
  4903.     for(i = 0; i < ap->NumArgs-1; ++i)
  4904.       DoOutput("(%s), ", ap->Args[i].ArgName);
  4905.     return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
  4906.   }
  4907.  
  4908.   if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
  4909.     return 1;
  4910.  
  4911.   if(flags & FUNCFLAG_TAG)
  4912.   {
  4913.     /* do not create MUI_NewObject */
  4914.     if(strcmp(name, "MUI_NewObject") && strcmp(name, "PM_MakeItem"))
  4915.     {
  4916.       DoOutput("#ifndef NO_INLINE_STDARG\n");
  4917.       DoOutput("static __inline__ ");
  4918.       FuncCSTUBS(ap, flags|FUNCFLAG_EXTENDMODE, name);
  4919.  
  4920.       DoOutput("#define %s("/*)*/, name);
  4921.       for(i = 0; i < ap->NumArgs-1; ++i)
  4922.       {
  4923.         DoOutput("%s, ", ap->Args[i].ArgName);
  4924.       }
  4925.       DoOutput(/*(*/"tags...) ___%s(%s_BASE_NAME, "/*)*/, name, ShortBaseNameUpper);
  4926.       for(i = 0; i < ap->NumArgs-1; ++i)
  4927.         DoOutput("%s, ", ap->Args[i].ArgName);
  4928.       DoOutput(/*(*/"tags)\n");
  4929.       return DoOutput("#endif\n\n");
  4930.     }
  4931.     return Output_Error;
  4932.   }
  4933.  
  4934.   DoOutput("#define %s("/*)*/, name);
  4935.   if(ap->NumArgs)
  4936.   {
  4937.     for(i = 0; i < ap->NumArgs-1; ++i)
  4938.       DoOutput("%s, ", ap->Args[i].ArgName);
  4939.     DoOutput("%s", ap->Args[i].ArgName);
  4940.   }
  4941.   DoOutput(/*(*/") ({ \\\n"/*})*/);
  4942.  
  4943.   for(i = 0; i < ap->NumArgs; ++i)
  4944.   {
  4945.     sprintf((strptr)tempbuf, "_%s_%s", name, ap->Args[i].ArgName);
  4946.     DoOutput("  ");
  4947.     OutClibType(&cd->Args[i], (strptr) tempbuf);
  4948.     DoOutput(" = (%s); \\\n", ap->Args[i].ArgName);
  4949.   }
  4950.   if(Flags & FLAG_INLINENEW)
  4951.   {
  4952.     if(ap->NumArgs)
  4953.       DoOutput("  ({ \\\n"/*})*/);
  4954.     DoOutput("  register char * _%s__bn __asm(\"a6\") = (char *) ", name);
  4955.     if(BaseName)
  4956.       DoOutput("(%s_BASE_NAME);\\\n", ShortBaseNameUpper);
  4957.     else
  4958.     {
  4959.       for(i = 0; i < ap->NumArgs && ap->Args[i].ArgReg != REG_A6; ++i)
  4960.         ;
  4961.       if(i == ap->NumArgs)
  4962.         return 1;
  4963.       DoOutput("(%s);\\\n", ap->Args[i].ArgName);
  4964.     }
  4965.  
  4966.     DoOutput("  (("/*))*/);
  4967.     OutClibType(&cd->ReturnType, 0);
  4968.     DoOutput(" (*)("/*)*/);
  4969.     if(BaseName)
  4970.     {
  4971.       DoOutput("char * __asm(\"a6\")");
  4972.       if(ap->NumArgs)
  4973.         DoOutput(", ");
  4974.     }
  4975.     for(i = 0; i < ap->NumArgs; ++i)
  4976.     {
  4977.       OutClibType(&cd->Args[i], 0);
  4978.       DoOutput(" __asm(\"%s\")", RegNames[ap->Args[i].ArgReg]);
  4979.       if(i < ap->NumArgs-1)
  4980.         DoOutput(", ");
  4981.     }
  4982.     DoOutput(/*((*/")) \\\n");
  4983.     DoOutput(/*(*/"  (_%s__bn - %d))("/*)*/, name, ap->Bias);
  4984.     if(BaseName)
  4985.     {
  4986.       DoOutput("_%s__bn", name);
  4987.       if(ap->NumArgs)
  4988.         DoOutput(", ");
  4989.     }
  4990.     for(i = 0; i < ap->NumArgs; ++i)
  4991.     {
  4992.       if(ap->Args[i].ArgReg == REG_A6)
  4993.         DoOutput("_%s__bn", name);
  4994.       else
  4995.         DoOutput("_%s_%s", name, ap->Args[i].ArgName);
  4996.       if(i < ap->NumArgs-1)
  4997.         DoOutput(", ");
  4998.     }
  4999.     DoOutput(/*(*/"); \\\n");
  5000.     if(ap->NumArgs)
  5001.       DoOutput(/*({*/"});");
  5002.   }
  5003.   else
  5004.   {
  5005.     /* do A5 first, as it is more important */
  5006.     if(ap->Flags & AMIPRAGFLAG_A5USE)
  5007.     {
  5008.       a5 = 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
  5009.       for(i = 0; i < ap->NumArgs; ++i)
  5010.         a5 |= 1<<ap->Args[i].ArgReg;
  5011.       a5 &= 0xFFF;
  5012.       if(a5 == 0xFFF)
  5013.       {
  5014.         DoError(ERR_INLINE_AX_SWAPREG, ap->Line, RegNamesUpper[REG_A5]);
  5015.         a5 = 0;
  5016.       }
  5017.       else
  5018.       {
  5019.         for(i = 0; (a5 & 1) && a5; ++i)
  5020.           a5 >>= 1;
  5021.         a5 = i; /* this is our A5 swap register */
  5022.       }
  5023.     }
  5024.     if(ap->Flags & AMIPRAGFLAG_A4USE)
  5025.     {
  5026.       a4 = 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
  5027.       for(i = 0; i < ap->NumArgs; ++i)
  5028.         a4 |= 1<<ap->Args[i].ArgReg;
  5029.       a4 &= 0xFFF;
  5030.       if(a4 == 0xFFF)
  5031.       {
  5032.         DoError(ERR_INLINE_AX_SWAPREG, ap->Line, RegNamesUpper[REG_A4]);
  5033.         a4 = 0;
  5034.       }
  5035.       else
  5036.       {
  5037.         for(i = 0; (a4 & 1) && a4; ++i)
  5038.           a4 >>= 1;
  5039.         a4 = i; /* this is our A4 swap register */
  5040.       }
  5041.     }
  5042.     if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
  5043.       noret = 1; /* this is a void function */
  5044.     else
  5045.     {
  5046.       sprintf((strptr)tempbuf, "_%s__re", name);
  5047.       DoOutput("  ");
  5048.       OutClibType(&cd->ReturnType, (strptr) tempbuf);
  5049.       DoOutput(" = \\\n");
  5050.     }
  5051.     if(ap->NumArgs || !noret)
  5052.       DoOutput("  %s{ \\\n", noret ? "" : "(" /*})*/);
  5053.     if(BaseName)
  5054.       DoOutput("  register %s const __%s__bn __asm(\"a6\") = (%s) (%s_BASE_NAME);\\\n",
  5055.       GetBaseType(), name, GetBaseType(), ShortBaseNameUpper);
  5056.  
  5057.     if(!noret)
  5058.     {
  5059.       sprintf((strptr)tempbuf, "__%s__re", name);
  5060.       DoOutput("  register ");
  5061.       OutClibType(&cd->ReturnType, (strptr) tempbuf);
  5062.       DoOutput(" __asm(\"d0\"); \\\n");
  5063.     }
  5064.     for(i = 0; i < ap->NumArgs; ++i)
  5065.     {
  5066.       uint32 reg;
  5067.  
  5068.       reg = ap->Args[i].ArgReg;
  5069.       if(a5 && reg == REG_A5) reg = a5; /* we need to switch */
  5070.       if(a4 && reg == REG_A4) reg = a4; /* we need to switch */
  5071.  
  5072.       sprintf((strptr)tempbuf, "__%s_%s", name, ap->Args[i].ArgName);
  5073.       DoOutput("  register ");
  5074.       OutClibType(&cd->Args[i], (strptr) tempbuf);
  5075.       DoOutput(" __asm(\"%s\") = (%s); \\\n", RegNames[reg], (strptr) (tempbuf+1));
  5076.     }
  5077.     DoOutput("  __asm volatile (\""/*)*/);
  5078.     if(a5) DoOutput("exg a5,%s\\n\\t", RegNames[a5]);
  5079.     if(a4) DoOutput("exg a4,%s\\n\\t", RegNames[a4]);
  5080.     DoOutput("jsr a6@(-%d:W)", ap->Bias);
  5081.     if(a4) DoOutput("\\n\\texg a4,%s", RegNames[a4]);
  5082.     if(a5) DoOutput("\\n\\texg a5,%s", RegNames[a5]);
  5083.     DoOutput("\" \\\n");
  5084.  
  5085.     if(noret)
  5086.       DoOutput("  : \\\n");
  5087.     else
  5088.       DoOutput("  : \"=r\"(__%s__re) \\\n", name);
  5089.     DoOutput("  :");
  5090.     if(BaseName)
  5091.       DoOutput(" \"r\"(__%s__bn)%s", name, ap->NumArgs ? "," : "");
  5092.     for(i = 0; i < ap->NumArgs; ++i)
  5093.     {
  5094.       DoOutput(" \"r\"(__%s_%s)", name, ap->Args[i].ArgName);
  5095.       if(i < ap->NumArgs-1)
  5096.         DoOutput(",");
  5097.     }
  5098.     DoOutput(/*(*/"  \\\n  : %s\"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\", \"cc\", \"memory\"); \\\n",
  5099.     noret ? "\"d0\", " : "");
  5100.  
  5101.     if(!noret)
  5102.       DoOutput("  __%s__re; \\\n", name);
  5103.  
  5104.     if(ap->NumArgs || !noret)
  5105.       DoOutput(/*({*/"  }%s \\\n", noret ? "" : ");");
  5106.  
  5107.     if(!noret)
  5108.       DoOutput("  _%s__re; \\\n", name);
  5109.   }
  5110.  
  5111.   return DoOutput(/*({*/"})\n\n");
  5112. }
  5113.  
  5114. uint32 FuncInline(struct AmiPragma *ap, uint32 flags, strptr name)
  5115. {
  5116.   uint32 noret = 0, a45 = 0, j;
  5117.   int32 fp = -1, i;
  5118.   struct ClibData *cd;
  5119.  
  5120.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
  5121.     return 1;
  5122.  
  5123.   Flags |= FLAG_DONE; /* We did something */
  5124.  
  5125.   if(flags & FUNCFLAG_ALIAS)
  5126.   {
  5127.     if(flags & FUNCFLAG_TAG)
  5128.       return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
  5129.       Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name, ap->TagName);
  5130.  
  5131.     DoOutput("#define %s("/*)*/, name);
  5132.     for(i = 0; i < ap->NumArgs-1; ++i)
  5133.       DoOutput("%s, ", ap->Args[i].ArgName);
  5134.     DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
  5135.     for(i = 0; i < ap->NumArgs-1; ++i)
  5136.       DoOutput("(%s), ", ap->Args[i].ArgName);
  5137.     return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
  5138.   }
  5139.  
  5140.   if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
  5141.     return 1;
  5142.  
  5143.   if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
  5144.     noret = 1; /* this is a void function */
  5145.  
  5146.   if(ap->Flags & AMIPRAGFLAG_A5USE)
  5147.     a45 = REG_A5;
  5148.   if(ap->Flags & AMIPRAGFLAG_A4USE)
  5149.   {
  5150.     if(a45)
  5151.     {
  5152.       DoError(ERR_INLINE_A4_AND_A5, ap->Line);
  5153.       return 1; /* skip this entry */
  5154.     }
  5155.     a45 = REG_A4;
  5156.   }
  5157.   if(a45 && (ap->Flags & AMIPRAGFLAG_D7USE))
  5158.   {
  5159.     DoError(ERR_INLINE_D7_AND_A45, ap->Line);
  5160.     return 1; /* skip this entry */
  5161.   }
  5162.  
  5163.   if((flags & FUNCFLAG_TAG))
  5164.   {
  5165.     if(Flags & FLAG_INLINENEW)
  5166.     {
  5167.       DoOutput("#ifndef NO_%sINLINE_STDARG\n",
  5168.       Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "");
  5169.       if(!strcmp(name, "MUI_NewObject") || !strcmp(name, "PM_MakeItem"))
  5170.       {
  5171.         DoOutput("__inline ");
  5172.         FuncCSTUBS(ap, flags, name);
  5173.         /* call CSTUBS, as this equals the method used there */
  5174.       }
  5175.       else
  5176.       {
  5177.         DoOutput("#define %s("/*)*/, name);
  5178.         for(i = 0; i < ap->NumArgs-1; ++i)
  5179.         {
  5180.           DoOutput("%s, ", ap->Args[i].ArgName);
  5181.         }
  5182.         DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
  5183.         ap->FuncName);
  5184.         for(i = 0; i < ap->NumArgs-1; ++i)
  5185.           DoOutput("(%s), ", ap->Args[i].ArgName);
  5186.         DoOutput("("/*)*/);
  5187.         OutClibType(&cd->Args[i], 0);
  5188.         DoOutput(/*({((*/") _tags);})\n");
  5189.       }
  5190.       return DoOutput("#endif\n\n");
  5191.     }
  5192.     else if((Flags & (FLAG_INLINESTUB|FLAG_MORPHOS)) == (FLAG_INLINESTUB|FLAG_MORPHOS))
  5193.     {
  5194.       int32 n, d, tagl, local;
  5195.  
  5196.       n = 9-ap->NumArgs;
  5197.       d = n & 1 ? 4 : 0;
  5198.       tagl = 8 + (Flags2 & FLAG2_DIRECTVARARGS ? 0 : 64);
  5199.       local = (n * 4+d+8+15) & ~15;   /* size of the stack frame */
  5200.  
  5201.       /* Stack frame:
  5202.        *   0- 3: next frame ptr
  5203.        *   4- 7: save lr
  5204.        *   8-71: struct Caos
  5205.        *  72-72+n*4+d+8-1: tag list start
  5206.        *   ?-local-1: padding
  5207.        */
  5208.  
  5209.        DoOutput("asm(\"\n"/*)*/
  5210.        "\t.align\t2\n"
  5211.        "\t.globl\t%s\n"
  5212.        "\t.type\t%s,@function\n"
  5213.        "%s:\n"
  5214.        "\tstwu\t1,-%ld(1)\n" /* create stack frame */
  5215.        "\tmflr\t0\n"
  5216.        "\tstw\t0,%ld(1)\n",
  5217.        name, name, name, local, local+4);
  5218.  
  5219.        /* If n is odd, one tag is split between regs and stack.
  5220.         * Copy its ti_Data together with the ti_Tag. */
  5221.        if(d)
  5222.          DoOutput("\tlwz\t0,%ld(1)\n", local+8); /* read ti_Data */
  5223.  
  5224.        /* Save the registers */
  5225.        for(i = ap->NumArgs; i <= 8; ++i)
  5226.          DoOutput("\tstw\t%ld,%ld(1)\n", i+2, (i-ap->NumArgs) * 4+tagl);
  5227.  
  5228.        if(d)
  5229.          DoOutput("\tstw\t0,%ld(1)\n", tagl+n * 4); /* write ti_Data */
  5230.  
  5231.        /* Add TAG_MORE */
  5232.        DoOutput("\tli\t0,2\n"
  5233.        "\tstw\t0,%ld(1)\n" /* add TAG_MORE */
  5234.        "\taddi\t0,1,%ld\n"
  5235.        "\tstw\t0,%ld(1)\n", /* ti_Data=&stack_params */
  5236.        tagl+n * 4+d, local+8+d, tagl+n * 4+d+4);
  5237.  
  5238.        if(Flags2 & FLAG2_DIRECTVARARGS)
  5239.        {
  5240.          DoOutput("\taddi\t%d,1,%ld\n" /* vararg_reg=&saved regs */
  5241.          "\tbl\t%s\n", ap->NumArgs+2, tagl, name);
  5242.        }
  5243.        else
  5244.        {
  5245.  
  5246.          if(!BaseName)
  5247.          {
  5248.            DoError(ERR_MISSING_BASENAME, ap->Line);
  5249.            return 1;
  5250.          }
  5251.          /* Caos.Offset = -fD_GetOffset(obj) */
  5252.          DoOutput("\tli\t0,%d\n"
  5253.          "\tstw\t0,8(1)\n", -ap->Bias);
  5254.  
  5255.          /* Save the non-varargs registers in the Caos struct. */
  5256.          for(i=0; i < ap->NumArgs-1; ++i)
  5257.          {
  5258.            DoOutput("\tstw\t%ld,%d(1)\n", i+3, 8+4+(ap->Args[i].ArgReg * 4));
  5259.          }
  5260.  
  5261.          DoOutput("\taddi\t0,1,%ld\n"
  5262.          "\tlis\t3,%s@ha\n"
  5263.          "\tstw\t0,%d(1)\n" /* Caos.reg_xx = taglist */
  5264.          "\tlwz\t12,%s@l(3)\n"
  5265.          "\tlwz\t11,88(2)\n"
  5266.          "\tstw\t12,68(1)\n" /* Caos.reg_a6=libbase */
  5267.          "\tmtctr\t11\n"
  5268.          "\taddi\t3,1,8\n"
  5269.          "\tbctrl\n", /* EmulCallOS() */
  5270.          tagl, BaseName, 12+(4 * ap->Args[i].ArgReg), BaseName);
  5271.       }
  5272.       DoOutput("\tlwz\t0,%ld(1)\n" /* clear stack frame & return */
  5273.       "\tmtlr\t0\n"
  5274.       "\taddi\t1,1,%ld\n"
  5275.       "\tblr\n"
  5276.       /*(*/"\t.size\t%s,$-%s\n\");\n\n", local+4, local, name, name);
  5277.     }
  5278.     else
  5279.     {
  5280.       DoOutput("%s%s__inline ", Flags & FLAG_INLINESTUB ? "" : "extern ",
  5281.       Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "static " : "");
  5282.       return FuncCSTUBS(ap, flags, name);
  5283.       /* call CSTUBS, as this equals the method used there */
  5284.     }
  5285.   }
  5286.  
  5287.   if(Flags & FLAG_INLINENEW) /* new style */
  5288.   {
  5289.     strptr funcpar = "";
  5290.     DoOutput("#define %s("/*)*/, name);
  5291.  
  5292.     for(i = 0; i < cd->NumArgs; ++i)
  5293.     {
  5294.       if(cd->Args[i].Flags & CPP_FLAG_FUNCTION)
  5295.         funcpar = "FP";
  5296.     }
  5297.  
  5298.     if(ap->NumArgs)
  5299.     {
  5300.       for(i = 0; i < ap->NumArgs-1; ++i)
  5301.         DoOutput("%s, ", ap->Args[i].ArgName);
  5302.       DoOutput("%s", ap->Args[i].ArgName);
  5303.     }
  5304.     DoOutput(/*(*/") \\\n\tLP%d%s%s%s%s(0x%x, "/*)*/, ap->NumArgs,
  5305.     (noret ? "NR" : ""), (a45 ? RegNamesUpper[a45] : (strptr) ""),
  5306.     (BaseName ? "" : "UB"), funcpar, ap->Bias);
  5307.     if(!noret)
  5308.     {
  5309.       OutClibType(&cd->ReturnType, 0);
  5310.       DoOutput(", ");
  5311.     }
  5312.     DoOutput("%s, ", name);
  5313.  
  5314.     for(i = 0; i < ap->NumArgs; ++i)
  5315.     {
  5316.       j = ap->Args[i].ArgReg;
  5317.       if(a45 && (j == REG_A4 || j == REG_A5))
  5318.         j = REG_D7;
  5319.       if(cd->Args[i].Flags & CPP_FLAG_FUNCTION)
  5320.       {
  5321.         if(fp != -1)
  5322.         {
  5323.           DoError(ERR_MULTIPLEFUNCTION, ap->Line);
  5324.           DoOutput("void *");
  5325.         }
  5326.         else
  5327.         {
  5328.           DoOutput("__fpt"); fp = i;
  5329.         }
  5330.       }
  5331.       else
  5332.         OutClibType(&cd->Args[i], 0);
  5333.   
  5334.       DoOutput(", %s, %s%s", ap->Args[i].ArgName, RegNames[j],
  5335.       (i == ap->NumArgs-1 && !BaseName ? "" : ", "));
  5336.     }
  5337.  
  5338.     if(BaseName) /* was "##base" used? */
  5339.       DoOutput("\\\n\t, %s_BASE_NAME", ShortBaseNameUpper);
  5340.  
  5341.     if(fp >= 0)
  5342.     {
  5343.       DoOutput(", ");
  5344.       OutClibType(&cd->Args[fp], "__fpt");
  5345.     }
  5346.  
  5347.     if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
  5348.       DoOutput(", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
  5349.  
  5350.     return DoOutput(/*(*/")\n\n");
  5351.   }
  5352.  
  5353.   /* old mode or stubs mode */
  5354.  
  5355.   if((Flags & (FLAG_INLINESTUB|FLAG_MORPHOS)) != (FLAG_INLINESTUB|FLAG_MORPHOS))
  5356.     DoOutput("%s%s__inline ", Flags & (FLAG_INLINESTUB|FLAG_MORPHOS) ? "" : "extern ",
  5357.     Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "static " : "");
  5358.   OutClibType(&cd->ReturnType, 0);
  5359.   DoOutput("\n%s(%s"/*)*/, name, (BaseName ?
  5360.   (ap->NumArgs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
  5361.  
  5362.   for(i = 0; i < ap->NumArgs; ++i)
  5363.   {
  5364.     OutClibType(&cd->Args[i], ap->Args[i].ArgName);
  5365.     if(i < ap->NumArgs-1)
  5366.       DoOutput(", ");
  5367.   }
  5368.  
  5369.   if(Flags & FLAG_POWERUP)
  5370.   {
  5371.     DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
  5372.     "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
  5373.     "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
  5374.     "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
  5375.     "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
  5376.     "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
  5377.     "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
  5378.  
  5379.     if(ap->NumArgs)
  5380.     {
  5381.       for(i = 0; i < ap->NumArgs; ++i)
  5382.       {
  5383.         DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
  5384.         RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
  5385.       }
  5386.     }
  5387.  
  5388.     DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
  5389.  
  5390.     if(BaseName)
  5391.       DoOutput("\tMyCaos.a6\t\t= (ULONG) %s_BASE_NAME;\n", ShortBaseNameUpper);
  5392.     if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
  5393.       DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
  5394.     else
  5395.     {
  5396.       DoOutput("\treturn(("/*))*/);
  5397.       OutClibType(&cd->ReturnType, 0);
  5398.       DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
  5399.     }
  5400.     return Output_Error;
  5401.   }
  5402.   else if( Flags & FLAG_MORPHOS)
  5403.   {
  5404.     DoOutput(/*(*/")\n{\n\tstruct EmulCaos MyCaos;\n"/*}*/);
  5405.  
  5406.     if(ap->NumArgs)
  5407.     {
  5408.       for(i = 0; i < ap->NumArgs; ++i)
  5409.       {
  5410.         DoOutput("\tMyCaos.reg_%s\t\t= (ULONG) %s;\n",
  5411.         RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
  5412.       }
  5413.     }
  5414.  
  5415.     DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
  5416.     if(BaseName)
  5417.       DoOutput("\tMyCaos.reg_a6\t\t= (ULONG) %s_BASE_NAME;\n", ShortBaseNameUpper);
  5418.  
  5419.     if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
  5420.       DoOutput(/*{*/"\t(*MyEmulHandle->EmulCallOS)(&MyCaos);\n}\n\n");
  5421.     else
  5422.     {
  5423.       DoOutput("\treturn(("/*))*/);
  5424.       OutClibType(&cd->ReturnType, 0);
  5425.       DoOutput(/*{((*/")(*MyEmulHandle->EmulCallOS)(&MyCaos));\n}\n\n");
  5426.     }
  5427.     return Output_Error;
  5428.   }
  5429.  
  5430.   DoOutput(/*(*/")\n{\n%s"/*}*/, (BaseName ? "  BASE_EXT_DECL\n" : ""));
  5431.  
  5432.   if(!noret)
  5433.   {
  5434.     DoOutput("  register ");
  5435.     OutClibType(&cd->ReturnType, "res");
  5436.     DoOutput(" __asm(\"d0\");\n");
  5437.   }
  5438.  
  5439.   if(BaseName)
  5440.     DoOutput("  register %s a6 __asm(\"a6\") = %s_BASE_NAME;\n", GetBaseType(), ShortBaseNameUpper);
  5441.  
  5442.   for(i = 0; i < ap->NumArgs; ++i)
  5443.   {
  5444.     j = ap->Args[i].ArgReg;
  5445.     if(a45 && (j == REG_A4 || j == REG_A5))
  5446.       j = REG_D7;
  5447.  
  5448.     DoOutput("  register ");
  5449.     OutClibType(&cd->Args[i], RegNames[j]);
  5450.     DoOutput(" __asm(\"%s\") = %s;\n", RegNames[j], ap->Args[i].ArgName);
  5451.   }
  5452.  
  5453.   if(a45)
  5454.   {
  5455.     DoOutput("  __asm volatile (\"exg d7,%s\\n\\t"/*)*/
  5456.     "jsr a6@(-0x%x:W)\\n\\texg d7,%s\"\n", RegNames[a45],
  5457.     ap->Bias, RegNames[a45]);
  5458.   }
  5459.   else
  5460.     DoOutput("  __asm volatile (\"jsr a6@(-0x%x:W)\"\n"/*)*/, ap->Bias);
  5461.  
  5462.   DoOutput(noret ? "  : /* No Output */\n" : "  : \"=r\" (res)\n");
  5463.  
  5464.   DoOutput("  : ");
  5465.   if(BaseName)
  5466.     DoOutput("\"r\" (a6)%s", (ap->NumArgs ? ", ": ""));
  5467.  
  5468.   for(i = 0; i < ap->NumArgs; ++i)
  5469.   {
  5470.     j = ap->Args[i].ArgReg;
  5471.     if(a45 && (j == REG_A4 || j == REG_A5))
  5472.       j = REG_D7;
  5473.  
  5474.     DoOutput("\"r\" (%s)%s", RegNames[j], (i < ap->NumArgs-1 ? ", " : ""));
  5475.   }
  5476.  
  5477.   DoOutput("\n  : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
  5478.  
  5479.   if(noret)
  5480.     return DoOutput(/*({*/", \"cc\", \"memory\");\n}\n\n");
  5481.   else
  5482.     return DoOutput(/*({*/", \"cc\", \"memory\");\n  return res;\n}\n\n");
  5483. }
  5484.  
  5485.  
  5486. /* new style inlines designed by Bernardo Innocenti */
  5487. uint32 FuncInlineNS(struct AmiPragma *ap, uint32 flags, strptr name)
  5488. {
  5489.   int32 i;
  5490.   struct ClibData *cd;
  5491.  
  5492.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
  5493.     return 1;
  5494.  
  5495.   Flags |= FLAG_DONE; /* We did something */
  5496.  
  5497.   if(flags & FUNCFLAG_ALIAS)
  5498.   {
  5499.     if(flags & FUNCFLAG_TAG)
  5500.       return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n", name, ap->TagName);
  5501.  
  5502.     DoOutput("#define %s("/*)*/, name);
  5503.     for(i = 0; i < ap->NumArgs-1; ++i)
  5504.       DoOutput("%s, ", ap->Args[i].ArgName);
  5505.     DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
  5506.     for(i = 0; i < ap->NumArgs-1; ++i)
  5507.       DoOutput("(%s), ", ap->Args[i].ArgName);
  5508.     return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
  5509.   }
  5510.  
  5511.   if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
  5512.     return 1;
  5513.  
  5514.   if((flags & FUNCFLAG_TAG))
  5515.   {
  5516.     if(!(Flags2 & FLAG2_INLINEMAC))
  5517.     {
  5518.       DoOutput("static __inline ");
  5519.       return FuncCSTUBS(ap, flags, name);
  5520.       /* call CSTUBS, as this equals the method used there */
  5521.     }
  5522.     else
  5523.     {
  5524.       DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/, Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name);
  5525.       for(i = 0; i < ap->NumArgs-1; ++i)
  5526.         DoOutput("%s, ", ap->Args[i].ArgName);
  5527.       DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
  5528.       ap->FuncName);
  5529.       for(i = 0; i < ap->NumArgs-1; ++i)
  5530.         DoOutput("(%s), ", ap->Args[i].ArgName);
  5531.       DoOutput("("/*)*/);
  5532.       OutClibType(&cd->Args[i], 0);
  5533.       return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
  5534.     }
  5535.   }
  5536.  
  5537.   if(Flags2 & FLAG2_INLINEMAC)
  5538.   {
  5539.     DoOutput("#define %s("/*)*/, name);
  5540.     for(i = 0; i < ap->NumArgs; ++i)
  5541.     {
  5542.       DoOutput("%s", ap->Args[i].ArgName);
  5543.       if(i < ap->NumArgs-1)
  5544.         DoOutput(", ");
  5545.     }
  5546.     DoOutput(/*(*/") \\\n\t");
  5547.   }
  5548.   else
  5549.   {
  5550.     DoOutput("static __inline ");
  5551.     OutClibType(&cd->ReturnType, 0);
  5552.     DoOutput(" %s("/*)*/, name);
  5553.     for(i = 0; i < ap->NumArgs; ++i)
  5554.     {
  5555.       OutClibType(&cd->Args[i], ap->Args[i].ArgName);
  5556.       if(i < ap->NumArgs-1)
  5557.         DoOutput(", ");
  5558.     }
  5559.     DoOutput(/*(*/")\n{\n  "/*}*/);
  5560.     if(!IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
  5561.       DoOutput("return ");
  5562.   }
  5563.   DoOutput("(("/*))*/);
  5564.   OutClibType(&cd->ReturnType, 0);
  5565.   DoOutput(" (*)("/*)*/);
  5566.   for(i = 0; i < ap->NumArgs; ++i)
  5567.   {
  5568.     OutClibType(&cd->Args[i], 0);
  5569.     DoOutput(" __asm(\"%s\")", RegNames[ap->Args[i].ArgReg]);
  5570.     if(i < ap->NumArgs-1)
  5571.       DoOutput(", ");
  5572.   }
  5573.   if(BaseName)
  5574.   {
  5575.     if(ap->NumArgs)
  5576.       DoOutput(", ");
  5577.     DoOutput("%s __asm(\"a6\")", GetBaseType());
  5578.   }
  5579.   DoOutput(/*((*/"))");
  5580.   if(Flags2 & FLAG2_INLINEMAC)
  5581.     DoOutput(" \\");
  5582.   if(BaseName)
  5583.     DoOutput(/*(*/"\n  (((char *) %s_BASE_NAME) - %d))("/*)*/, ShortBaseNameUpper, ap->Bias);
  5584.   else
  5585.   {
  5586.     for(i = 0; i < ap->NumArgs && ap->Args[i].ArgReg != REG_A6; ++i)
  5587.       ;
  5588.     if(i == ap->NumArgs)
  5589.       return 1;
  5590.     DoOutput(/*(*/"\n  (((char *) %s) - %d))("/*)*/, ap->Args[i].ArgName, ap->Bias);
  5591.   }
  5592.   for(i = 0; i < ap->NumArgs; ++i)
  5593.   {
  5594.     DoOutput("%s", ap->Args[i].ArgName);
  5595.     if(i < ap->NumArgs-1)
  5596.       DoOutput(", ");
  5597.   }
  5598.   if(BaseName)
  5599.   {
  5600.     if(ap->NumArgs)
  5601.       DoOutput(", ");
  5602.     DoOutput("%s_BASE_NAME", ShortBaseNameUpper);
  5603.   }
  5604.  
  5605.   if(Flags2 & FLAG2_INLINEMAC)
  5606.     DoOutput(/*(*/")\n");
  5607.   else
  5608.     DoOutput(/*{(*/");\n}\n");
  5609.  
  5610.   return DoOutput("\n");
  5611. }
  5612.  
  5613. uint32 FuncPowerUP(struct AmiPragma *ap, uint32 flags, strptr name)
  5614. {
  5615.   int32 i;
  5616.   struct ClibData *cd;
  5617.  
  5618.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
  5619.     return 1;
  5620.  
  5621.   Flags |= FLAG_DONE; /* We did something */
  5622.  
  5623.   if(flags & FUNCFLAG_ALIAS)
  5624.   {
  5625.     if(flags & FUNCFLAG_TAG)
  5626.       return DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s %s\n#endif\n\n", name, ap->TagName);
  5627.  
  5628.     DoOutput("#define %s("/*)*/, name);
  5629.     for(i = 0; i < ap->NumArgs-1; ++i)
  5630.       DoOutput("%s, ", ap->Args[i].ArgName);
  5631.     DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
  5632.     for(i = 0; i < ap->NumArgs-1; ++i)
  5633.       DoOutput("(%s), ", ap->Args[i].ArgName);
  5634.     return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
  5635.   }
  5636.  
  5637.   if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
  5638.     return 1;
  5639.  
  5640.   if(flags & FUNCFLAG_TAG)
  5641.   {
  5642.     DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s("/*)*/, name);
  5643.     for(i = 0; i < ap->NumArgs-1; ++i)
  5644.       DoOutput("%s, ", ap->Args[i].ArgName);
  5645.     DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*)})*/,
  5646.     ap->FuncName);
  5647.     for(i = 0; i < ap->NumArgs-1; ++i)
  5648.       DoOutput("(%s), ", ap->Args[i].ArgName);
  5649.     DoOutput("("/*)*/);
  5650.     OutClibType(&cd->Args[i], 0);
  5651.     return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
  5652.   }
  5653.  
  5654.   DoOutput("#define\t%s("/*)*/, name);
  5655.  
  5656.   if(ap->NumArgs)
  5657.   {
  5658.   
  5659.     for(i = 0; i < ap->NumArgs-1; ++i)
  5660.       DoOutput("%s, ", ap->Args[i].ArgName);
  5661.     DoOutput(/*(*/"%s)\t_%s("/*)*/, ap->Args[i].ArgName, name);
  5662.  
  5663.     if(BaseName)
  5664.       DoOutput("%s_BASE_NAME, ", ShortBaseNameUpper);
  5665.  
  5666.     for(i = 0; i < ap->NumArgs-1; ++i)
  5667.       DoOutput("%s, ", ap->Args[i].ArgName);
  5668.     DoOutput(/*(*/"%s)\n\n", ap->Args[i].ArgName);
  5669.   }
  5670.   else if(BaseName)
  5671.     DoOutput(/*(*/")\t_%s(%s_BASE_NAME)\n\n", name, ShortBaseNameUpper);
  5672.   else
  5673.     DoOutput(/*(*/")\t_%s()\n\n", name);
  5674.  
  5675.   DoOutput("static __inline ");
  5676.   OutClibType(&cd->ReturnType, 0);
  5677.   
  5678.   DoOutput("\n_%s("/*)*/, name);
  5679.   if(BaseName)
  5680.     DoOutput("void * %s%s", BaseName, ap->NumArgs ? ", " : "");
  5681.  
  5682.   for(i = 0; i < ap->NumArgs; ++i)
  5683.   {
  5684.     OutClibType(&cd->Args[i], ap->Args[i].ArgName);
  5685.     if(i < ap->NumArgs-1)
  5686.       DoOutput(", ");
  5687.   }
  5688.  
  5689.   DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
  5690.   "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
  5691.   "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
  5692.   "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
  5693.   "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
  5694.   "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
  5695.   "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
  5696.  
  5697.   if(ap->NumArgs)
  5698.   {
  5699.     for(i = 0; i < ap->NumArgs; ++i)
  5700.     {
  5701.       DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
  5702.       RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
  5703.     }
  5704.   }
  5705.  
  5706.   DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
  5707.  
  5708.   if(BaseName)
  5709.     DoOutput("\tMyCaos.a6\t\t= (ULONG) %s;\n", BaseName);
  5710.   if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
  5711.     DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
  5712.   else
  5713.   {
  5714.     DoOutput("\treturn(("/*))*/);
  5715.     OutClibType(&cd->ReturnType, 0);
  5716.     DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
  5717.   }
  5718.   return Output_Error;
  5719. }
  5720.  
  5721. uint32 FuncFPCUnit(struct AmiPragma *ap, uint32 flags, strptr name)
  5722. {
  5723.   int32 i;
  5724.   struct ClibData *cd;
  5725.  
  5726.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
  5727.     return 1;
  5728.   else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
  5729.     return 1;
  5730.  
  5731.   if(!FuncFPCType(ap, flags, name))
  5732.     return 0;
  5733.  
  5734.   DoOutput("BEGIN\n  ASM\n\tMOVE.L\tA6,-(A7)\n");
  5735.  
  5736.   for(i = 0; i < ap->NumArgs; ++i)
  5737.     DoOutput("\tMOVE%s.L\t%s,%s\n", ap->Args[i].ArgReg >= REG_A0 ? "A" : "",
  5738.     ap->Args[i].ArgName, RegNamesUpper[ap->Args[i].ArgReg]);
  5739.  
  5740.   if(BaseName)
  5741.     DoOutput("\tMOVEA.L\t%s,A6\n", BaseName);
  5742.   DoOutput("\tJSR\t-%03d(A6)\n\tMOVEA.L\t(A7)+,A6\n", ap->Bias);
  5743.  
  5744.   if(!IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
  5745.   {
  5746.     if(!cd->ReturnType.PointerDepth &&
  5747.     cd->ReturnType.Flags == CPP_FLAG_BOOLEAN)
  5748.       DoOutput("\tTST.W\tD0\n\tBEQ.B\t@end\n\tMOVEQ\t#1,D0\n"
  5749.       "  @end:\tMOVE.B\tD0,@RESULT\n");
  5750.     else
  5751.       DoOutput("\tMOVE.L\tD0,@RESULT\n");
  5752.   }
  5753.   return DoOutput("  END;\nEND;\n\n");
  5754. }
  5755.  
  5756. uint32 FuncFPCType(struct AmiPragma *ap, uint32 flags, strptr name)
  5757. {
  5758.   uint32 ret = 1;
  5759.   int32 i;
  5760.   struct ClibData *cd;
  5761.  
  5762.   if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
  5763.     return 1;
  5764.   else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
  5765.     return 1;
  5766.  
  5767.   if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
  5768.   {
  5769.     ret = 0; DoOutput("PROCEDURE %s", name);
  5770.   }
  5771.   else
  5772.     DoOutput("FUNCTION %s", name);
  5773.  
  5774.   if(ap->NumArgs)
  5775.   {
  5776.     DoOutput("("/*)*/);
  5777.     for(i = 0; i < ap->NumArgs;)
  5778.     {
  5779.       OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
  5780.       if(++i != ap->NumArgs)
  5781.         DoOutput("; ");
  5782.     }
  5783.     DoOutput(/*(*/")");
  5784.   }
  5785.  
  5786.   if(ret)
  5787.     OutPASCALType(&cd->ReturnType, "", 1);
  5788.  
  5789.   Flags |= FLAG_DONE; /* We did something */
  5790.  
  5791.   return DoOutput(";\n");
  5792. }
  5793.  
  5794. uint32 FuncBMAP(struct AmiPragma *ap, uint32 flags, strptr name)
  5795. {
  5796.   uint8 reg, i;
  5797.  
  5798.   if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_A6USE|AMIPRAGFLAG_A5USE|AMIPRAGFLAG_PPC))
  5799.     return 1;
  5800.  
  5801.   Flags |= FLAG_DONE; /* We did something */
  5802.  
  5803.   for(i = 0; BMAPSpecial[i]; ++i)
  5804.   {
  5805.     if(!stricmp(name, BMAPSpecial[i]))
  5806.     {
  5807.       DoOutput("x"); break;
  5808.     }
  5809.   }
  5810.  
  5811.   DoOutput(name);
  5812.   reg = 0;                      DoOutputDirect(®, 1);
  5813.   reg = (-ap->Bias)>>8;         DoOutputDirect(®, 1);
  5814.   reg = -ap->Bias;              DoOutputDirect(®, 1);
  5815.   for(i = 0; i < ap->NumArgs; ++i)
  5816.   {
  5817.     reg = 1+ap->Args[i].ArgReg; DoOutputDirect(®, 1);
  5818.   }
  5819.   reg = 0;
  5820.   return DoOutputDirect(®, 1);
  5821. }
  5822.  
  5823. uint32 FuncVBCCInline(struct AmiPragma *ap, uint32 flags, strptr name)
  5824. {
  5825.   struct ClibData *cd;
  5826.   strptr c1, c2;
  5827.   int32 i, k;
  5828.  
  5829.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
  5830.     return 1;
  5831.  
  5832.   if(!(cd = GetClibFunc(name, ap, flags)))
  5833.     return 1;
  5834.  
  5835.   c1 = Flags & FLAG_NEWSYNTAX ? "(" : ""; /*)*/
  5836.   c2 = Flags & FLAG_NEWSYNTAX ? "," : "("; /*)*/
  5837.  
  5838.   Flags |= FLAG_DONE; /* We did something */
  5839.  
  5840.   if(flags & FUNCFLAG_TAG)
  5841.   {
  5842.     DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && (__STDC_VERSION__ >= 199901L)\n");
  5843.   }
  5844.  
  5845.   if(flags & FUNCFLAG_ALIAS)
  5846.   {
  5847.     DoOutput("#define %s("/*)*/, name);
  5848.     for(i = 0; i < ap->NumArgs-1; ++i)
  5849.       DoOutput("%s, ", ap->Args[i].ArgName);
  5850.     DoOutput(/*(*/"%s) __%s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
  5851.     for(i = 0; i < ap->NumArgs; ++i)
  5852.       DoOutput("(%s), ", ap->Args[i].ArgName);
  5853.     return DoOutput(/*(*/"%s)\n%s\n", BaseName, flags & FUNCFLAG_TAG ? "#endif\n" : "");
  5854.   }
  5855.  
  5856.   if(flags & FUNCFLAG_TAG)
  5857.   {
  5858.     if(ap->Args[ap->NumArgs-1].ArgReg >= REG_D2 && ap->Args[ap->NumArgs-1].ArgReg <= REG_D7)
  5859.       DoOutput("__regsused(\"d0/d1/%s/a0/a1\") ", RegNames[ap->Args[ap->NumArgs-1].ArgReg]);
  5860.     else if(ap->Args[ap->NumArgs-1].ArgReg >= REG_A2 && ap->Args[ap->NumArgs-1].ArgReg <= REG_A7)
  5861.       DoOutput("__regsused(\"d0/d1/a0/a1/%s\") ", RegNames[ap->Args[ap->NumArgs-1].ArgReg]);
  5862.   }
  5863.  
  5864.   OutClibType(&cd->ReturnType, 0);
  5865.   DoOutput(" __%s("/*)*/, name);
  5866.  
  5867.   if(!(Flags2 & FLAG2_OLDVBCC) && BaseName)
  5868.   {
  5869.     DoOutput("__reg(\"a6\") %s", GetBaseType());
  5870.     if(ap->NumArgs)
  5871.       DoOutput(", ");
  5872.   }
  5873.  
  5874.   k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-1 : ap->NumArgs;
  5875.   for(i = 0; i < k; ++i)
  5876.   {
  5877.     DoOutput("__reg(\"%s\") ", RegNames[ap->Args[i].ArgReg]);
  5878.     if(ap->Args[i].ArgReg >= REG_A0 && ap->Args[i].ArgReg <= REG_A7
  5879.     && !(cd->Args[i].Flags & (CPP_FLAG_POINTER|CPP_FLAG_FUNCTION)))
  5880.     {
  5881.       DoOutput("void * %s", ap->Args[i].ArgName);
  5882.     }
  5883.     else
  5884.       OutClibType(&cd->Args[i], ap->Args[i].ArgName);
  5885.     if(i < ap->NumArgs-1)
  5886.       DoOutput(", ");
  5887.   }
  5888.  
  5889.   if((Flags2 & FLAG2_OLDVBCC) && BaseName)
  5890.   {
  5891.     if(ap->NumArgs)
  5892.       DoOutput(", ");
  5893.     DoOutput("__reg(\"a6\") %s", GetBaseType());
  5894.   }
  5895.  
  5896.   if(flags & FUNCFLAG_TAG)
  5897.   {
  5898.     if(cd->Args[k].Type != CPP_TYPE_VARARGS)
  5899.     {
  5900.       OutClibType(&cd->Args[k], ap->Args[k].ArgName);
  5901.       DoOutput(", ");
  5902.     }
  5903.     DoOutput(/*((*/"...)=\"\\tmove%s.l\\ta7,%s\\n\\tjsr\\t%s-%d%sa6)\";\n",
  5904.     ap->Args[k].ArgReg >= REG_A0 ? "a" : "", RegNames[ap->Args[k].ArgReg], c1,
  5905.     ap->Bias, c2);
  5906.   }
  5907.   else
  5908.     DoOutput(/*((*/")=\"\\tjsr\\t%s-%d%sa6)\";\n", c1, ap->Bias, c2);
  5909.  
  5910.   k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-2 : ap->NumArgs;
  5911.   DoOutput("#define %s("/*)*/, name);
  5912.   for(i = 0; i < k; ++i)
  5913.   {
  5914.     DoOutput("%s", ap->Args[i].ArgName);
  5915.     if(i < ap->NumArgs-1)
  5916.       DoOutput(", ");
  5917.   }
  5918.   if(flags & FUNCFLAG_TAG)
  5919.   {
  5920.     if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
  5921.       DoOutput("%s, ", ap->Args[k].ArgName);
  5922.     DoOutput("...");
  5923.   }
  5924.   DoOutput(/*(*/") __%s("/*)*/, name);
  5925.   if(!(Flags2 & FLAG2_OLDVBCC) && BaseName)
  5926.   {
  5927.     DoOutput("%s", BaseName);
  5928.     if(ap->NumArgs)
  5929.       DoOutput(", ");
  5930.   }
  5931.   for(i = 0; i < k; ++i)
  5932.   {
  5933.     if(ap->Args[i].ArgReg >= REG_A0 && ap->Args[i].ArgReg <= REG_A7
  5934.     && !(cd->Args[i].Flags & (CPP_FLAG_POINTER|CPP_FLAG_FUNCTION)))
  5935.     {
  5936.       DoOutput("(void *)");
  5937.     }
  5938.     DoOutput("(%s)", ap->Args[i].ArgName);
  5939.     if(i < ap->NumArgs-1)
  5940.       DoOutput(", ");
  5941.   }
  5942.   if((Flags2 & FLAG2_OLDVBCC) && BaseName)
  5943.   {
  5944.     if(ap->NumArgs)
  5945.       DoOutput(", ");
  5946.     DoOutput("%s", BaseName);
  5947.   }
  5948.   if(flags & FUNCFLAG_TAG)
  5949.   {
  5950.     if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
  5951.       DoOutput("(%s), ", ap->Args[k].ArgName);
  5952.     DoOutput("__VA_ARGS__");
  5953.   }
  5954.  
  5955.   return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ? "#endif\n" : "");
  5956. }
  5957.  
  5958. uint32 FuncVBCCWOSInline(struct AmiPragma *ap, uint32 flags, strptr name)
  5959. {
  5960.   struct ClibData *cd;
  5961.   int32 i;
  5962.  
  5963.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_M68K))
  5964.     return 1;
  5965.  
  5966.   if(!(cd = GetClibFunc(name, ap, flags)))
  5967.     return 1;
  5968.  
  5969.   if(!BaseName)
  5970.   {
  5971.     DoError(ERR_MISSING_BASENAME, ap->Line);
  5972.     return 1;
  5973.   }
  5974.  
  5975.   Flags |= FLAG_DONE; /* We did something */
  5976.  
  5977.   if(!(flags & FUNCFLAG_ALIAS))
  5978.   {
  5979.     OutClibType(&cd->ReturnType, 0);
  5980.     DoOutput(" __%s("/*)*/, name);
  5981.  
  5982.     if(!(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)))
  5983.     {
  5984.       DoOutput("%s", GetBaseType());
  5985.       if(ap->NumArgs)
  5986.         DoOutput(", ");
  5987.     }
  5988.  
  5989.     for(i = 0; i < ap->NumArgs; ++i)
  5990.     {
  5991.       OutClibType(&cd->Args[i], ap->Args[i].ArgName);
  5992.       if(i < ap->NumArgs-1)
  5993.         DoOutput(", ");
  5994.     }
  5995.  
  5996.     DoOutput(/*(*/")=\"");
  5997.     if(ap->Flags & AMIPRAGFLAG_PPC0)
  5998.     {
  5999.       DoOutput("\\t.extern\\t_%s\\n"
  6000.                "\\tlwz\\t%s11,_%s(%s2)\\n"
  6001.                "\\tlwz\\t%s0,-%d(%s11)\\n"
  6002.                "\\tmtlr\\t%s0\\n"
  6003.                "\\tblrl",
  6004.                BaseName, PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix,
  6005.                ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
  6006.     }
  6007.     else if(ap->Flags & AMIPRAGFLAG_PPC2)
  6008.     {
  6009.       DoOutput("\\tstw\\t%s2,20(%s1)\\n"
  6010.                "\\t.extern\\t_%s\\n"
  6011.                "\\tlwz\\t%s2,_%s(%s2)\\n"
  6012.                "\\tlwz\\t%s0,-%d(%s2)\\n"
  6013.                "\\tmtlr\\t%s0\\n"
  6014.                "\\tblrl\\n"
  6015.                "\\tlwz\\t%s2,20(%s1)",
  6016.                PPCRegPrefix, PPCRegPrefix, BaseName, PPCRegPrefix, BaseName,
  6017.                PPCRegPrefix, PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix,
  6018.                PPCRegPrefix, PPCRegPrefix);
  6019.     }
  6020.     else
  6021.     {
  6022.       DoOutput("\\tlwz\\t%s0,-%d(%s3)\\n"
  6023.                "\\tmtlr\\t%s0\\n"
  6024.                "\\tblrl",
  6025.                PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
  6026.     }
  6027.   
  6028.     DoOutput("\";\n");
  6029.   }
  6030.  
  6031.   DoOutput("#define %s("/*)*/, name);
  6032.   for(i = 0; i < ap->NumArgs; ++i)
  6033.   {
  6034.     DoOutput("%s", ap->Args[i].ArgName);
  6035.     if(i < ap->NumArgs-1)
  6036.       DoOutput(", ");
  6037.   }
  6038.   DoOutput(/*(*/") __%s("/*)*/, ap->FuncName);
  6039.   if(!(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)))
  6040.   {
  6041.     DoOutput("%s", BaseName);
  6042.     if(ap->NumArgs)
  6043.       DoOutput(", ");
  6044.   }
  6045.   for(i = 0; i < ap->NumArgs; ++i)
  6046.   {
  6047.     DoOutput("(%s)", ap->Args[i].ArgName);
  6048.     if(i < ap->NumArgs-1)
  6049.       DoOutput(", ");
  6050.   }
  6051.  
  6052.   return DoOutput(/*(*/")\n\n");
  6053. }
  6054.  
  6055. uint32 FuncVBCCMorphInline(struct AmiPragma *ap, uint32 flags, strptr name)
  6056. {
  6057.   struct ClibData *cd;
  6058.   int32 i, k;
  6059.  
  6060.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
  6061.     return 1;
  6062.  
  6063.   if(!(cd = GetClibFunc(name, ap, flags)))
  6064.     return 1;
  6065.  
  6066.   Flags |= FLAG_DONE; /* We did something */
  6067.  
  6068.   if(flags & FUNCFLAG_TAG)
  6069.   {
  6070.     DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && (__STDC_VERSION__ >= 199901L)\n");
  6071.   }
  6072.  
  6073.   if(flags & FUNCFLAG_ALIAS)
  6074.   {
  6075.     DoOutput("#define %s("/*)*/, name);
  6076.     for(i = 0; i < ap->NumArgs-1; ++i)
  6077.       DoOutput("%s, ", ap->Args[i].ArgName);
  6078.     DoOutput(/*(*/"%s) __%s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
  6079.     for(i = 0; i < ap->NumArgs; ++i)
  6080.       DoOutput("(%s), ", ap->Args[i].ArgName);
  6081.     return DoOutput(/*(*/"%s)\n%s\n", BaseName, flags & FUNCFLAG_TAG ? "#endif\n" : "");
  6082.   }
  6083.  
  6084.   OutClibType(&cd->ReturnType, 0);
  6085.   DoOutput(" __%s("/*)*/, name);
  6086.  
  6087.   if(BaseName)
  6088.   {
  6089.     DoOutput("%s", GetBaseType());
  6090.     if(ap->NumArgs)
  6091.       DoOutput(", ");
  6092.   }
  6093.  
  6094.   if(flags & FUNCFLAG_TAG)
  6095.   {
  6096.     for(i = ap->NumArgs+(BaseName?1:0); i <= 8; ++i)
  6097.       DoOutput("long, ");
  6098.   }
  6099.  
  6100.   k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-1 : ap->NumArgs;
  6101.   for(i = 0; i < k; ++i)
  6102.   {
  6103.     OutClibType(&cd->Args[i], ap->Args[i].ArgName);
  6104.     if(i < ap->NumArgs-1)
  6105.       DoOutput(", ");
  6106.   }
  6107.  
  6108.   if(flags & FUNCFLAG_TAG)
  6109.   {
  6110.     if(cd->Args[k].Type != CPP_TYPE_VARARGS)
  6111.     {
  6112.       OutClibType(&cd->Args[k], ap->Args[k].ArgName);
  6113.       DoOutput(", ");
  6114.     }
  6115.     DoOutput("...");
  6116.   }
  6117.  
  6118.   DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s11,100(%s2)\\n\"\n",
  6119.   PPCRegPrefix, PPCRegPrefix);
  6120.   k = 3;
  6121.   if(BaseName)
  6122.     DoOutput("\t\"\\tstw\\t%s%d,56(%s2)\\n\"\n", PPCRegPrefix, k++, PPCRegPrefix);
  6123.   if(flags & FUNCFLAG_TAG)
  6124.   {
  6125.     if((i = ap->NumArgs+(BaseName?1:0)) <= 8)
  6126.       k += 8+1-i;
  6127.   }
  6128.   
  6129.   DoOutput("\t\"\\tmtlr\\t%s11\\n\"\n", PPCRegPrefix);
  6130.   for(i = 0; i < ap->NumArgs; ++i)
  6131.   {
  6132.     if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
  6133.     {
  6134.       if(k <= 7+3)
  6135.         DoOutput("\t\"\\tstw\\t%s%ld,", PPCRegPrefix, k++);
  6136.       else
  6137.         DoOutput("\t\"\\tlwz\\t%s11,%ld(%s1)\\n\"\n\t\"\\tstw\\t%s11,", PPCRegPrefix,
  6138.         8+(k++-11)*4, PPCRegPrefix, PPCRegPrefix);
  6139.     }
  6140.     else
  6141.       DoOutput("\t\"\\taddi\\t%s4,%s1,%d\\n\"\n\t\"\\tstw\\t%s4,", PPCRegPrefix,
  6142.       PPCRegPrefix, (2+k-11)*4, PPCRegPrefix);
  6143.     DoOutput("%d(%s2)\\n\"\n", 4*ap->Args[i].ArgReg, PPCRegPrefix);
  6144.   }
  6145.   DoOutput("\t\"\\tli\\t%s3,-%d\\n\"\n\t\"\\tblrl\";\n", PPCRegPrefix, ap->Bias);
  6146.  
  6147.   k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-2 : ap->NumArgs;
  6148.   DoOutput("#define %s("/*)*/, name);
  6149.   for(i = 0; i < k; ++i)
  6150.   {
  6151.     DoOutput("%s", ap->Args[i].ArgName);
  6152.     if(i < ap->NumArgs-1)
  6153.       DoOutput(", ");
  6154.   }
  6155.   if(flags & FUNCFLAG_TAG)
  6156.   {
  6157.     if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
  6158.       DoOutput("%s, ", ap->Args[k].ArgName);
  6159.     DoOutput("...");
  6160.   }
  6161.   DoOutput(/*(*/") __%s("/*)*/, name);
  6162.   if(BaseName)
  6163.   {
  6164.     DoOutput("%s", BaseName);
  6165.     if(ap->NumArgs)
  6166.       DoOutput(", ");
  6167.   }
  6168.   if(flags & FUNCFLAG_TAG)
  6169.   {
  6170.     for(i = ap->NumArgs+(BaseName?1:0); i <= 8; ++i)
  6171.       DoOutput("0, ");
  6172.   }
  6173.   for(i = 0; i < k; ++i)
  6174.   {
  6175.     DoOutput("(%s)", ap->Args[i].ArgName);
  6176.     if(i < ap->NumArgs-1)
  6177.       DoOutput(", ");
  6178.   }
  6179.   if(flags & FUNCFLAG_TAG)
  6180.   {
  6181.     if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
  6182.       DoOutput("(%s), ", ap->Args[k].ArgName);
  6183.     DoOutput("__VA_ARGS__");
  6184.   }
  6185.  
  6186.   return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ? "#endif\n" : "");
  6187. }
  6188.  
  6189. uint32 FuncVBCCWOSText(struct AmiPragma *ap, uint32 flags, strptr name)
  6190. {
  6191.   uint32 i, k, count, ofs;
  6192.   struct ClibData *cd = 0;
  6193.  
  6194.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG))
  6195.     return 1;
  6196.  
  6197.   if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_PPC) &&!(cd = GetClibFunc(name, ap, flags)))
  6198.     return 1;
  6199.  
  6200.   if((ap->Flags & AMIPRAGFLAG_PPC) && !BaseName &&
  6201.   ((ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)) || !(Flags & FLAG_WOSLIBBASE)))
  6202.   {
  6203.     DoError(ERR_MISSING_BASENAME, ap->Line);
  6204.     return 1;
  6205.   }
  6206.  
  6207.   Flags |= FLAG_DONE;
  6208.  
  6209.   if(Flags & FLAG_SINGLEFILE)
  6210.   {
  6211.     if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  6212.  
  6213.     if(HEADER)
  6214.     {
  6215.       DoOutput("\n");
  6216.       DoOutputDirect(HEADER, headersize);
  6217.     }
  6218.   }
  6219.  
  6220.   if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
  6221.     DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
  6222.  
  6223.   if(Flags & FLAG_SINGLEFILE)
  6224.     DoOutput("\t.file\t\"%s.s\"\n", name);
  6225.   DoOutput("\t.align\t3\n");
  6226.   if(Flags & FLAG_WOSLIBBASE)  /* PPCBase already in r3, LibBase in r4 */
  6227.   {
  6228.     if(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2))
  6229.       DoOutput("\t.extern _%s\n", BaseName);
  6230.     DoOutput("\t.global __%s\n__%s:\n", name, name);
  6231.   }
  6232.   else
  6233.   {
  6234.     if(BaseName)
  6235.       DoOutput("\t.extern _%s\n", BaseName);
  6236.     if(!(ap->Flags & AMIPRAGFLAG_PPC))
  6237.       DoOutput("\t.extern _PowerPCBase\n");
  6238.     DoOutput("\t.global _%s\n_%s:\n", name, name);
  6239.   }
  6240.  
  6241.   if(ap->Flags & AMIPRAGFLAG_PPC2)
  6242.   {
  6243.     DoOutput("\tstw\t%s2,20(%s1)\n"
  6244.              "\tmflr\t%s0\n"
  6245.              "\tstw\t%s0,16(%s1)\n"
  6246.              "\tlwz\t%s2,_%s(%s2)\n"
  6247.              "\tlwz\t%s0,-%d(%s2)\n"
  6248.              "\tmtlr\t%s0\n"
  6249.              "\tblrl\n"
  6250.              "\tlwz\t%s0,16(%s1)\n"
  6251.              "\tlwz\t%s2,20(%s1)\n"
  6252.              "\tmtlr\t%s0\n"
  6253.              "\tblr\n",
  6254.     PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
  6255.     PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias-2, PPCRegPrefix,
  6256.     PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
  6257.   }
  6258.   else if(ap->Flags & AMIPRAGFLAG_PPC0)
  6259.   {
  6260.     DoOutput("\tlwz\t%s11,_%s(%s2)\n\tlwz\t%s0,-%d(%s11)\n\tmtlr\t%s0\n\tblrl\n",
  6261.     PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
  6262.   }
  6263.   else if(ap->Flags & AMIPRAGFLAG_PPC)
  6264.   {
  6265.     count = ap->NumArgs;
  6266.     if(Flags & FLAG_WOSLIBBASE) /* LibBase already in r3 */
  6267.     {
  6268.       /* init stack frame */
  6269.       i = (count <= 8) ? 32 : ((56+(count-8)*8+15)&~15); /* stksize */
  6270.       DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
  6271.       PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix);
  6272.  
  6273.       if(count > 8)
  6274.       {
  6275.         /* extra arguments must be passed on the stack */
  6276.         k = 32-(count-8); /* firstreg */
  6277.  
  6278.         DoOutput("\tstmw\t%s%ld,%ld(%s1)\n\tlmw\t%s%ld,%ld(%s1)\n",
  6279.         PPCRegPrefix, k, 56+(count-8)*4, PPCRegPrefix, PPCRegPrefix, k,
  6280.         i+56, PPCRegPrefix);
  6281.         if(flags & FUNCFLAG_TAG)
  6282.           DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix, PPCRegPrefix,
  6283.           i+20+count*4);
  6284.         DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix, k, PPCRegPrefix);
  6285.       }
  6286.       else if(flags & FUNCFLAG_TAG)
  6287.       {
  6288.         DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix, count+3,
  6289.         PPCRegPrefix, i+20+count*4);
  6290.         --count;
  6291.       }
  6292.     }
  6293.     else        /* Args must be shifted! */
  6294.     {
  6295.       /* init stack frame */
  6296.       i = (count < 8) ? 32 : ((56+(count-7)*8+15)&~15); /* stksize */
  6297.       DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
  6298.       PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix);
  6299.  
  6300.       if(count > 7)
  6301.       {
  6302.         /* extra arguments must be passed on the stack */
  6303.         if(count == 8)
  6304.         {
  6305.           /* special case: move 8th argument into stack frame */
  6306.           if(flags & FUNCFLAG_TAG)
  6307.             DoOutput("\taddi\t%s10,%s1,%ld\n", PPCRegPrefix, PPCRegPrefix,
  6308.             i+20+count*4);
  6309.           DoOutput("\tstw\t%s10,56(%s1)\n", PPCRegPrefix, PPCRegPrefix);
  6310.         }
  6311.         else
  6312.         {
  6313.           k = 32-(count-7); /* firstreg */
  6314.  
  6315.           DoOutput("\tstmw\t%s%ld,%ld(%s1)\n"
  6316.                    "\tmr\t%s%ld,%s10\n"
  6317.                    "\tlmw\t%s%ld,%ld(%s1)\n",
  6318.                    PPCRegPrefix, k, 56+(count-7)*4, PPCRegPrefix,
  6319.                    PPCRegPrefix, k, PPCRegPrefix, PPCRegPrefix, k+1,
  6320.                    i+56, PPCRegPrefix);
  6321.           if(flags & FUNCFLAG_TAG)
  6322.             DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix,
  6323.             PPCRegPrefix, i+20+count*4);
  6324.           DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix, k, PPCRegPrefix);
  6325.         }
  6326.       }
  6327.       else if(flags & FUNCFLAG_TAG)
  6328.       {
  6329.         DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix, count+3,
  6330.         PPCRegPrefix, i+20+count*4);
  6331.         --count;
  6332.       }
  6333.  
  6334.       /* shift all arguments into their following register */
  6335.       for(k=(count<8)?count:7; k > 0; --k)
  6336.         DoOutput("\tmr\t%s%ld,%s%ld\n", PPCRegPrefix, 3+k, PPCRegPrefix, 2+k);
  6337.  
  6338.       /* load library base and LVO, then call LVO via LR */
  6339.       DoOutput("\tlwz\t%s3,_%s(%s2)\n", PPCRegPrefix, BaseName, PPCRegPrefix);
  6340.     }
  6341.  
  6342.     /* call LVO */
  6343.     DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtlr\t%s0\n\tblrl\n", PPCRegPrefix,
  6344.     ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
  6345.  
  6346.     /* cleanup stack frame and return */
  6347.     if(count > 8)
  6348.     {
  6349.       k = Flags & FLAG_WOSLIBBASE ? 8 : 7;      /* restore saved regs */
  6350.       DoOutput("\tlmw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, 32-(count-k),
  6351.       56+(count-k)*4, PPCRegPrefix);
  6352.     }
  6353.  
  6354.     DoOutput("\taddi\t%s1,%s1,%ld\n\tlwz\t%s0,8(%s1)\n\tmtlr\t%s0\n\tblr\n",
  6355.     PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
  6356.   }
  6357.   else
  6358.   {
  6359.     DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-0xB0(%s1)\n",
  6360.     PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
  6361.  
  6362.     /* clear PP_Flags, PP_Stack and PP_StackSize */
  6363.     DoOutput("\tli\t%s11,0\n\tstw\t%s11,0x28(%s1)\n\tstw\t%s11,0x2C(%s1)\n"
  6364.     "\tstw\t%s11,0x30(%s1)\n", PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
  6365.     PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
  6366.  
  6367.     if(Flags & FLAG_WOSLIBBASE)
  6368.       DoOutput("\tli\t%s11,-%d\n\tstw\t%s4,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n"
  6369.       "\tstw\t%s4,0x6C(%s1)\n", PPCRegPrefix, ap->Bias, PPCRegPrefix,
  6370.       PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
  6371.     else if(!BaseName)
  6372.       DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,0x24(%s1)\n", PPCRegPrefix,
  6373.       ap->Bias, PPCRegPrefix, PPCRegPrefix);
  6374.     else
  6375.       DoOutput("\tlwz\t%s0,_%s(%s2)\n\tli\t%s11,-%d\n"
  6376.       "\tstw\t%s0,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n\tstw\t%s0,0x6c(%s1)\n",
  6377.       PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias,
  6378.       PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
  6379.       PPCRegPrefix);
  6380.  
  6381.     ofs = Flags & FLAG_WOSLIBBASE ? 2 : 0;
  6382.     k = ap->NumArgs - (flags & FUNCFLAG_TAG ? 1 : 0);
  6383.     for(i = 0; i < k; ++i)
  6384.     {
  6385.       if(i + ofs <= 7)
  6386.       {
  6387.         if(ap->Args[i].ArgReg == REG_A6)
  6388.           DoOutput("\tstw\t%s%ld,0x20(%s1)\n", PPCRegPrefix, i+3+ofs, PPCRegPrefix);
  6389.         DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3+ofs);
  6390.       }
  6391.       else
  6392.       {
  6393.         DoOutput("\tlwz\t%s11,%ld(%s1)\n", PPCRegPrefix, (i+1+ofs)*4+196, PPCRegPrefix);
  6394.         if(ap->Args[i].ArgReg == REG_A6)
  6395.           DoOutput("\tstw\t%s11,0x20(%s1)\n", PPCRegPrefix, PPCRegPrefix);
  6396.         DoOutput("\tstw\t%s11,", PPCRegPrefix);
  6397.       }
  6398.       DoOutput("%d(%s1)\n", 0x34+4*ap->Args[i].ArgReg, PPCRegPrefix);
  6399.     }
  6400.     if(flags & FUNCFLAG_TAG)
  6401.     {
  6402.       if((i+ofs) <= 7 && cd->Args[i].Type != CPP_TYPE_VARARGS)
  6403.         DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i+3+ofs,
  6404.         0xC4+(ap->NumArgs+ofs)*4, PPCRegPrefix);
  6405.       DoOutput("\taddi\t%s11,%s1,%ld\n\tstw\t%s11,", PPCRegPrefix,
  6406.       PPCRegPrefix, 0xC4+(ap->NumArgs+ofs)*4, PPCRegPrefix);
  6407.       DoOutput("%d(%s1)\n", 0x34+4*ap->Args[i].ArgReg, PPCRegPrefix);
  6408.     }
  6409.  
  6410.     if(!(Flags & FLAG_WOSLIBBASE))
  6411.       DoOutput("\tlwz\t%s3,_PowerPCBase(%s2)\n", PPCRegPrefix, PPCRegPrefix);
  6412.  
  6413.     DoOutput("\taddi\t%s4,%s1,0x20\n\tlwz\t%s0,-298(%s3)\n\tmtlr\t%s0\n\tblrl\n"
  6414.     "\tlwz\t%s3,0x34(%s1)\n\taddi\t%s1,%s1,0xB0\n\tlwz\t%s0,8(%s1)\n\tmtlr\t%s0\n\tblr\n",
  6415.     PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
  6416.     PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
  6417.   }
  6418.  
  6419.   if(Flags & FLAG_WOSLIBBASE)
  6420.     return DoOutput("\t.type\t__%s,@function\n\t.size\t__%s,$-__%s\n\n",
  6421.     name, name, name);
  6422.   else
  6423.     return DoOutput("\t.type\t_%s,@function\n\t.size\t_%s,$-_%s\n\n",
  6424.     name, name, name);
  6425. }
  6426.  
  6427. uint32 FuncVBCCWOSCode(struct AmiPragma *ap, uint32 flags, strptr name)
  6428. {
  6429.   uint32 i, j, k, ofs, count;
  6430.   uint8 *data, *basepos = 0, *pbasepos = 0;
  6431.   struct ClibData *cd = 0;
  6432.  
  6433.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG))
  6434.     return 1;
  6435.  
  6436.   if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_PPC) && !(cd = GetClibFunc(name, ap, flags)))
  6437.     return 1;
  6438.  
  6439.   if((ap->Flags & AMIPRAGFLAG_PPC) && !BaseName &&
  6440.   ((ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)) || !(Flags & FLAG_WOSLIBBASE)))
  6441.   {
  6442.     DoError(ERR_MISSING_BASENAME, ap->Line);
  6443.     return 1;
  6444.   }
  6445.  
  6446.   Flags |= FLAG_DONE; /* We did something */
  6447.  
  6448.   i = strlen(name);
  6449.   if(Flags & FLAG_WOSLIBBASE)
  6450.    ++i;
  6451.   EndPutM32(tempbuf, HUNK_UNIT);
  6452.   EndPutM32(tempbuf+4, (i+3)>>2);
  6453.   DoOutputDirect(tempbuf, 8);
  6454.   DoOutput("%s%s", Flags & FLAG_WOSLIBBASE ? "_" : "", name);
  6455.   DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
  6456.  
  6457.   i = strlen(hunkname);
  6458.   EndPutM32(tempbuf, HUNK_NAME);
  6459.   EndPutM32(tempbuf+4, (i + 3)>>2);
  6460.   DoOutputDirect(tempbuf, 8);
  6461.   DoOutputDirect(hunkname, i);
  6462.   DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
  6463.  
  6464.   data = tempbuf+8; /* we need HUNK_PPC_CODE + size at start */
  6465.  
  6466.   if(ap->Flags & AMIPRAGFLAG_PPC2)
  6467.   {
  6468.     EndPutM32Inc(data, 0x90410014);             /* stw r2,20(r1) */
  6469.     EndPutM32Inc(data, 0x7C0802A6);             /* mflr r0 = mfspr r0,8 = get link register */
  6470.     EndPutM32Inc(data, 0x90010010);             /* stw r0,16(r1) */
  6471.     basepos = data;
  6472.     EndPutM32Inc(data, 0x80420000);             /* lwz r2,BaseName(r2) */
  6473.     EndPutM32Inc(data, 0x80030000 - ap->Bias);  /* lwz r0,-ap->Bias(r2) */
  6474.     EndPutM32Inc(data, 0x7C0803A6);             /* mtlr r0 = mtspr 8,r0 = restore link register */
  6475.     EndPutM32Inc(data, 0x4E800021);             /* blrl = bclrl 20,0 = jump */
  6476.     EndPutM32Inc(data, 0x80010010);             /* lwz r0,16(r1) */
  6477.     EndPutM32Inc(data, 0x80410014);             /* lwz r2,20(r1) */
  6478.     EndPutM32Inc(data, 0x7C0803A6);             /* mtlr r0 = mtspr 8,r0 = restore link register */
  6479.     EndPutM32Inc(data, 0x4E800020);             /* blr = bclr 20,0 = jump */
  6480.   }
  6481.   else if(ap->Flags & AMIPRAGFLAG_PPC0)
  6482.   {
  6483.     basepos = data;
  6484.     EndPutM32Inc(data, 0x81620000);             /* lwz r11,BaseName(r2) */
  6485.     EndPutM32Inc(data, 0x800C0000 - ap->Bias);  /* lwz r0,-ap->Bias(r11) */
  6486.     EndPutM32Inc(data, 0x7C0803A6);             /* mtlr r0 = mtspr 8,r0 = store link register */
  6487.     EndPutM32Inc(data, 0x4E800021);             /* blrl = bclrl 20,0 = jump */
  6488.   }
  6489.   else if(ap->Flags & AMIPRAGFLAG_PPC)
  6490.   {
  6491.     count = ap->NumArgs;
  6492.     if(Flags & FLAG_WOSLIBBASE) /* LibBase already in r3 */
  6493.     {
  6494.       /* init stack frame */
  6495.       i = (count <= 8) ? 32 : ((56+(count-8)*8+15)&~15);        /* stksize */
  6496.       EndPutM32Inc(data, 0x7C0802A6);                           /* mflr r0 = mfspr r0,8 = get link register */
  6497.       EndPutM32Inc(data, 0x90010008);                           /* stw r0,8(r1) */
  6498.       EndPutM32Inc(data, 0x94220000 - i);                       /* stwu r1,-i(r1) */
  6499.  
  6500.       if(count > 8)
  6501.       {
  6502.         /* extra arguments must be passed on the stack */
  6503.         k = 32-(count-8);                                               /* firstreg */
  6504.         EndPutM32Inc(data, 0xBC010000 + (k << 21) + (56+(count-8)*4));  /* stmw rk,X(r1) */
  6505.         EndPutM32Inc(data, 0xB8010000 + (k << 21) + (i+56));            /* lmw rk,Y(r1) */
  6506.         if(flags & FUNCFLAG_TAG)
  6507.           EndPutM32Inc(data, 0x3BE10000 + (i+20+count*4));              /* addi r31,r1,X */
  6508.         EndPutM32Inc(data, 0xBC010038 + (k << 21));                     /* stmw rk,56(r1) */
  6509.       }
  6510.       else if(flags & FUNCFLAG_TAG)
  6511.       {
  6512.         EndPutM32Inc(data, 0x38010000 + ((count+3)<<21) + (i+20+count*4)); /* addi rX,r1,Y */
  6513.         --count;
  6514.       }
  6515.     }
  6516.     else        /* Args must be shifted! */
  6517.     {
  6518.       /* init stack frame */
  6519.       i = (count < 8) ? 32 : ((56+(count-7)*8+15)&~15);         /* stksize */
  6520.       EndPutM32Inc(data, 0x7C0802A6);                           /* mflr r0 = mfspr r0,8 = get link register */
  6521.       EndPutM32Inc(data, 0x90010008);                           /* stw r0,8(r1) */
  6522.       EndPutM32Inc(data, 0x94220000 - i);                       /* stwu r1,-i(r1) */
  6523.  
  6524.       if(count > 7)
  6525.       {
  6526.         /* extra arguments must be passed on the stack */
  6527.         if(count == 8)
  6528.         {
  6529.           /* special case: move 8th argument into stack frame */
  6530.           if(flags & FUNCFLAG_TAG)
  6531.             EndPutM32Inc(data, 0x39410000 + (i+20+count*4));    /* addi r10,r1,X */
  6532.           EndPutM32Inc(data, 0x91410038);                       /* stw r10,56(r1) */
  6533.         }
  6534.         else
  6535.         {
  6536.           k = 32-(count-7); /* firstreg */
  6537.  
  6538.           EndPutM32Inc(data, 0xBC010000 + (k << 21) + (56+(count-7)*4));/* stmw rk,X(r1) */
  6539.           EndPutM32Inc(data, 0x7D405378 + (k<<16));                     /* mr rk,r10 = or rk,r10,r10 */
  6540.           EndPutM32Inc(data, 0xB8010000 + ((k+1) << 21) + (i+56));      /* lmw rk,Y(r1) */
  6541.           if(flags & FUNCFLAG_TAG)
  6542.             EndPutM32Inc(data, 0x3BE10000 + (i+20+count*4));            /* addi r31,r1,X */
  6543.           EndPutM32Inc(data, 0xBC010038 + (k << 21));                   /* stmw rk,56(r1) */
  6544.         }
  6545.       }
  6546.       else if(flags & FUNCFLAG_TAG)
  6547.       {
  6548.         EndPutM32Inc(data, 0x38010000 + ((count+3)<<21) + (i+20+count*4)); /* addi rX,r1,Y */
  6549.         --count;
  6550.       }
  6551.  
  6552.       /* shift all arguments into their following register */
  6553.       for(k=(count<8)?count:7; k > 0; --k)
  6554.         EndPutM32Inc(data, 0x7C000378 + ((3+k)<<16) + ((2+k)<<21) + ((2+k)<<11)); /* mr rX,rY = or rX,rY,rY */
  6555.  
  6556.       /* load library base and LVO, then call LVO via LR */
  6557.       basepos = data;
  6558.       EndPutM32Inc(data, 0x80620000);                                   /* lwz r3,BaseName(r2) */
  6559.     }
  6560.     /* call LVO */
  6561.     EndPutM32Inc(data, 0x80040000 - (ap->Bias-2));                      /* lwz r0,-(ap->Bias-2)(r3) */
  6562.     EndPutM32Inc(data, 0x7C0803A6);                                     /* mtlr r0 = mtspr 8,r0 = restore link register */
  6563.     EndPutM32Inc(data, 0x4E800021);                                     /* blrl = bclrl 20,0 = jump */
  6564.  
  6565.  
  6566.     /* cleanup stack frame and return */
  6567.     if(count > 8)
  6568.     {
  6569.       k = Flags & FLAG_WOSLIBBASE ? 8 : 7;      /* restore saved regs */
  6570.       EndPutM32Inc(data, 0xB8010000 + ((32-(count-k))<<21) + (56+(count-k)*4)); /* lmw rX,Y(r1) */
  6571.     }
  6572.     EndPutM32Inc(data, 0x38210000 + i);         /* addi r1,r1,i */
  6573.     EndPutM32Inc(data, 0x80010008);             /* lwz r0,8(r1) */
  6574.     EndPutM32Inc(data, 0x7C0803A6);             /* mtlr r0 = mtspr 8,r0 = restore link register */
  6575.     EndPutM32Inc(data, 0x4E800020);             /* blr = bclr 20,0 = jump */
  6576.   }
  6577.   else
  6578.   {
  6579.     EndPutM32Inc(data, 0x7C0802A6);             /* mflr r0 = mfspr r0,8 = get link register */
  6580.     EndPutM32Inc(data, 0x90010008);             /* stw r0,8(r1) = save link register in 8(r1) */
  6581.     EndPutM32Inc(data, 0x9421FF50);             /* stwu r1,-0xB0(r1) = store word from r1 in -0xB0(r1) and update r1 */
  6582.  
  6583.     EndPutM32Inc(data, 0x39600000);             /* li r11,0 = addi r11,r0,0 = clear r11 */
  6584.     EndPutM32Inc(data, 0x91610028);             /* stwu r11,0x28(r1) = clear PP_Flags */
  6585.     EndPutM32Inc(data, 0x9161002C);             /* stwu r11,0x2C(r1) = clear PP_Stack */
  6586.     EndPutM32Inc(data, 0x91610030);             /* stwu r11,0x30(r1) = clear PP_StackSize */
  6587.  
  6588.     if(Flags & FLAG_WOSLIBBASE)
  6589.     {
  6590.       EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
  6591.       EndPutM32Inc(data, 0x90810020);           /* stw r4,0x20(r1) = set PP_Code to Librarybase */
  6592.       EndPutM32Inc(data, 0x91610024);           /* stw r11,0x24(r1) = set PP_Offset to Bias value */
  6593.       EndPutM32Inc(data, 0x9081006C);           /* stw r4,0x6C(r1) = set A6 register */
  6594.     }
  6595.     else if(!BaseName)
  6596.     {
  6597.       EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
  6598.       EndPutM32Inc(data, 0x91610024);           /* stw r11,0x24(r1) = set PP_Offset to Bias value */
  6599.     }
  6600.     else
  6601.     {
  6602.       basepos = data;
  6603.       EndPutM32Inc(data, 0x80020000);           /* lwz r0,BaseName(r2)  --> 16BIT RELOC! */
  6604.       EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
  6605.       EndPutM32Inc(data, 0x90010020);           /* stw r0,0x20(r1) = set PP_Code to Librarybase */
  6606.       EndPutM32Inc(data, 0x91610024);           /* stw r11,0x24(r1) = set PP_Offset to Bias value */
  6607.       EndPutM32Inc(data, 0x9001006C);           /* stw r4,0x6C(r1) = set A6 register */
  6608.     }
  6609.   
  6610.     ofs = Flags & FLAG_WOSLIBBASE ? 2 : 0;
  6611.     k = ap->NumArgs - (flags & FUNCFLAG_TAG ? 1 : 0);
  6612.     for(i = 0; i < k; ++i)
  6613.     {
  6614.       j = 0x34+4*ap->Args[i].ArgReg; /* PP_Regs offset */
  6615.       if(i + ofs <= 7)
  6616.       {
  6617.         if(ap->Args[i].ArgReg == REG_A6)
  6618.           EndPutM32Inc(data, 0x90010020 + ((i+3+ofs)<<21));     /* stw rX,0x20(r1) */
  6619.         EndPutM32Inc(data, 0x90010000 + ((i+3+ofs)<<21) + j);   /* stw rX,j(r1) */
  6620.       }
  6621.       else
  6622.       {
  6623.         EndPutM32Inc(data, 0x81610000 + ((i+1+ofs)*4+0xC4));    /* lwz r11,X(r1) = get data from stack */
  6624.         if(ap->Args[i].ArgReg == REG_A6)
  6625.           EndPutM32Inc(data, 0x91610020);                       /* stw r11,0x20(r1) */
  6626.         EndPutM32Inc(data, 0x91610000 + j);                     /* stw r11,j(r1) */
  6627.       }
  6628.     }
  6629.     if(flags & FUNCFLAG_TAG)
  6630.     {
  6631.       j = (ap->NumArgs+ofs)*4+0xC4;
  6632.  
  6633.       if((i+ofs) <= 7 && cd->Args[i].Type != CPP_TYPE_VARARGS)
  6634.         EndPutM32Inc(data, 0x90010000 + ((i+3+ofs)<<21) + j);           /* stw rX,j(r1) */
  6635.       EndPutM32Inc(data, 0x39610000 + j);                               /* addi r11,r1,j */
  6636.       EndPutM32Inc(data, 0x91610000 + (0x34+4*ap->Args[i].ArgReg));     /* stw r11,X(r1) */
  6637.     }
  6638.  
  6639.     if(!(Flags & FLAG_WOSLIBBASE))
  6640.     {
  6641.       pbasepos = data;                  /* store 16BIT reloc offset */
  6642.       EndPutM32Inc(data, 0x80620000);   /* lwz r3,_PowerPCBase(r2) = get librarybase */
  6643.     }
  6644.     EndPutM32Inc(data, 0x38810020);     /* addi r4,r1,0x20 = {r4 := 0x20(r1)} */
  6645.     EndPutM32Inc(data, 0x8003FED6);     /* lwz r0,-298(r3) = load jumpin base */
  6646.     EndPutM32Inc(data, 0x7C0803A6);     /* mtlr r0 = mtspr 8,r0 = store link register */
  6647.     EndPutM32Inc(data, 0x4E800021);     /* blrl = bclrl 20,0 = jump */
  6648.     EndPutM32Inc(data, 0x80610034);     /* lwz r3,0x34(r1) = get result D0 */
  6649.     EndPutM32Inc(data, 0x382100B0);     /* addi r1,r1,0xB0 = free PRCArgs structure */
  6650.     EndPutM32Inc(data, 0x80010008);     /* lwz r0,8(r1) = get old link register */
  6651.     EndPutM32Inc(data, 0x7C0803A6);     /* mtlr r0 = mtspr 8,r0 = restore link register */
  6652.     EndPutM32Inc(data, 0x4E800020);     /* blr = bclr 20,0 = jump back */
  6653.   }
  6654.  
  6655.   EndPutM32(tempbuf, HUNK_PPC_CODE);
  6656.   EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
  6657.   DoOutputDirect(tempbuf, (data-tempbuf)&(~3));
  6658.  
  6659.   EndPutM32(tempbuf, HUNK_EXT);
  6660.   DoOutputDirect(tempbuf,4);
  6661.  
  6662.   /* here come the XDEF name references */
  6663.  
  6664.   if(Flags & FLAG_WOSLIBBASE)
  6665.   {
  6666.     if(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2))
  6667.       OutputXREF((basepos-tempbuf-8)+2, EXT_DEXT16, "_%s", BaseName);
  6668.     OutputXDEF(0, "__%s", name);
  6669.   }
  6670.   else
  6671.   {
  6672.     if(BaseName)
  6673.       OutputXREF((basepos-tempbuf-8)+2, EXT_DEXT16, "_%s", BaseName);
  6674.     if(!(ap->Flags & AMIPRAGFLAG_PPC))
  6675.       OutputXREF((pbasepos-tempbuf-8)+2, EXT_DEXT16, "_PowerPCBase");
  6676.     OutputXDEF(0, "_%s", name);
  6677.   }
  6678.   EndPutM32(tempbuf, 0);
  6679.   DoOutputDirect(tempbuf,4);
  6680.   if(!(Flags & FLAG_NOSYMBOL))
  6681.   {
  6682.     EndPutM32(tempbuf, HUNK_SYMBOL);
  6683.     DoOutputDirect(tempbuf,4);
  6684.     if(Flags & FLAG_WOSLIBBASE)
  6685.       OutputSYMBOL(0, "__%s", name);
  6686.     else
  6687.       OutputSYMBOL(0, "_%s", name);
  6688.     EndPutM32(tempbuf, 0);
  6689.     DoOutputDirect(tempbuf,4);
  6690.   }
  6691.   EndPutM32(tempbuf, HUNK_END);
  6692.  
  6693.   return DoOutputDirect(tempbuf,4);
  6694. }
  6695.  
  6696. uint32 FuncVBCCPUPText(struct AmiPragma *ap, uint32 flags, strptr name)
  6697. {
  6698.   int32 i;
  6699.  
  6700.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
  6701.     return 1;
  6702.  
  6703.   Flags |= FLAG_DONE;
  6704.  
  6705.   if(Flags & FLAG_SINGLEFILE)
  6706.   {
  6707.     if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  6708.  
  6709.     if(HEADER)
  6710.     {
  6711.       DoOutput("\n");
  6712.       DoOutputDirect(HEADER, headersize);
  6713.     }
  6714.   }
  6715.  
  6716.   if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
  6717.     DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
  6718.  
  6719.   if(Flags & FLAG_SINGLEFILE)
  6720.     DoOutput("\t.file\t\"%s.s\"\n", name);
  6721.   if(BaseName)
  6722.     DoOutput("\t.global %s\n", BaseName);
  6723.   DoOutput("\t.global PPCCallOS\n\t.global %s\n"
  6724.   "\t.align\t3\n%s:\n",name, name);
  6725.  
  6726.   if(flags & FUNCFLAG_TAG)
  6727.   {
  6728.     /* Hack the stack-frame for varargs.
  6729.        Build stack-frame, but save LR in our own stack-frame,
  6730.        because we have to overwrite the lower 8 bytes of the
  6731.        caller's frame. */
  6732.     DoOutput("\tstwu\t%s1,-128(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
  6733.     PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
  6734.  
  6735.     /* Save the caller's saved SP in our own stack-frame. */
  6736.     DoOutput("\tlwz\t%s11,128(%s1)\n\tstw\t%s11,96(%s1)\n", PPCRegPrefix,
  6737.     PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
  6738.  
  6739.     /* Store r3-r8 at the top of our stack-frame and r9-r10
  6740.        at the low 8 bytes of the caller's frame. This way all
  6741.        arguments will reside in one continuous area. */
  6742.     for(i=3+ap->NumArgs-1; i <= 10; ++i)
  6743.       DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i, 104+4*(i-3),
  6744.       PPCRegPrefix);
  6745.   }
  6746.   else
  6747.     DoOutput("\tstwu\t%s1,-96(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
  6748.     PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
  6749.  
  6750.   for(i = 0; i < ap->NumArgs; ++i)
  6751.   {
  6752.     if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
  6753.     {
  6754.       if(i <= 7)
  6755.         DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3);
  6756.       else
  6757.         DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix,
  6758.         100+(i+1-8)*4, PPCRegPrefix, PPCRegPrefix);
  6759.     }
  6760.     else
  6761.       DoOutput("\taddi\t%s11,%s1,%d\n\tstw\t%s11,", PPCRegPrefix,
  6762.       PPCRegPrefix, 100+ap->NumArgs*4, PPCRegPrefix);
  6763.     DoOutput("%d(%s1)\n", 36+4*ap->Args[i].ArgReg, PPCRegPrefix);
  6764.   }
  6765.  
  6766.   /* Now place the real function call */
  6767.   DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,8(%s1)\n" /* store offset in Chaos->caos_Un.Offset */
  6768.   "\tli\t%s11,1\n\tstw\t%s11,12(%s1)\n\tstw\t%s11,24(%s1)\n", PPCRegPrefix,
  6769.   ap->Bias, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
  6770.   PPCRegPrefix, PPCRegPrefix);
  6771.   /* set M68kCacheMode and PPCCacheMode to IF_CACHEFLUSHALL */
  6772.  
  6773.   if(BaseName)
  6774.   {
  6775.     if(Flags & FLAG_SMALLDATA)
  6776.       DoOutput("\tlwz\t%s11,%s@sdarx(%s13)\n", PPCRegPrefix, BaseName, PPCRegPrefix);
  6777.     else
  6778.       DoOutput("\tlis\t%s11,%s@ha\n\tlwz\t%s11,%s@l(%s11)\n", PPCRegPrefix,
  6779.       BaseName, PPCRegPrefix, BaseName, PPCRegPrefix);
  6780.     DoOutput("\tstw\t%s11,92(%s1)\n", PPCRegPrefix, PPCRegPrefix); /* store basepointer in A6 */
  6781.   }
  6782.  
  6783.   DoOutput("\taddi\t%s3,%s1,8\n\tbl\tPPCCallOS\n", PPCRegPrefix, PPCRegPrefix);
  6784.   if(flags & FUNCFLAG_TAG) /* Varargs. Rebuild the caller's stack-frame. */
  6785.     DoOutput("\tlwz\t%s11,96(%s1)\n\tstw\t%s11,128(%s1)\n"
  6786.     "\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,128\n",
  6787.     PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
  6788.     PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
  6789.   else
  6790.     DoOutput("\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,96\n",
  6791.     PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
  6792.  
  6793.   return DoOutput("\tblr\n\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n", name, name, name);
  6794. }
  6795.  
  6796. uint32 FuncVBCCPUPCode(struct AmiPragma *ap, uint32 flags, strptr name)
  6797. {
  6798.   int32 i, j=0, k, size;
  6799.   uint8 *data, *data2, *data3;
  6800.   struct ArHeader *arh;
  6801.  
  6802.   data = tempbuf;
  6803.  
  6804.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
  6805.     return 1;
  6806.  
  6807.   Flags |= FLAG_DONE;
  6808.  
  6809.   *(data++) = 0x7F;                                             /* eeh->e_ident[EI_MAG0] */
  6810.   *(data++) = 'E';                                              /* eeh->e_ident[EI_MAG1] */
  6811.   *(data++) = 'L';                                              /* eeh->e_ident[EI_MAG2] */
  6812.   *(data++) = 'F';                                              /* eeh->e_ident[EI_MAG3] */
  6813.   *(data++) = ELFCLASS32;                                       /* eeh->e_ident[EI_CLASS] */
  6814.   *(data++) = ELFDATA2MSB;                                      /* eeh->e_ident[EI_DATA] */
  6815.   *(data++) = EV_CURRENT;                                       /* eeh->e_ident[EI_VERSION] */
  6816.   *(data++) = 0; *(data++) = 0; *(data++) = 0;
  6817.   *(data++) = 0; *(data++) = 0; *(data++) = 0;
  6818.   *(data++) = 0; *(data++) = 0; *(data++) = 0;
  6819.   EndPutM16Inc(data, ET_REL);                                   /* eeh->e_type */
  6820.   EndPutM16Inc(data, EM_POWERPC);                               /* eeh->e_machine */
  6821.   EndPutM32Inc(data, EV_CURRENT);                               /* eeh->e_version */
  6822.   EndPutM32Inc(data, 0);                                        /* eeh->e_entry */
  6823.   EndPutM32Inc(data, 0);                                        /* eeh->e_phoff */
  6824.   data2 = data; data += 4;
  6825.   EndPutM32Inc(data, 0);                                        /* eeh->e_flags */
  6826.   EndPutM16Inc(data, 52);                                       /* eeh->e_ehsize */
  6827.   EndPutM16Inc(data, 0);                                        /* eeh->e_phentsize */
  6828.   EndPutM16Inc(data, 0);                                        /* eeh->e_phnum */
  6829.   EndPutM16Inc(data, 40);                                       /* eeh->e_shentsize */
  6830.   EndPutM16Inc(data, 6);                                        /* eeh->e_shnum */
  6831.   EndPutM16Inc(data, 3);                                        /* eeh->e_shstrndx - fourth table is string table */
  6832.  
  6833.   data3 = data;
  6834.   if(flags & FUNCFLAG_TAG)
  6835.   {
  6836.     /* Hack the stack-frame for varargs.
  6837.        Build stack-frame, but save LR in our own stack-frame,
  6838.        because we have to overwrite the lower 8 bytes of the
  6839.        caller's frame. */
  6840.     EndPutM32Inc(data, 0x9421FF80);                             /* stwu r1,-128(r1) */
  6841.     EndPutM32Inc(data, 0x7D6802A6);                             /* mflr r11 = mfspr r11,8 = get link register */
  6842.     EndPutM32Inc(data, 0x91610064);                             /* stw r11,100(r1) */
  6843.  
  6844.     /* Save the caller's saved SP in our own stack-frame. */
  6845.     EndPutM32Inc(data, 0x81610080);                             /* lwz r11,128(r1) */
  6846.     EndPutM32Inc(data, 0x91610060);                             /* stw r11,96(r1) */
  6847.  
  6848.     /* Store r3-r8 at the top of our stack-frame and r9-r10
  6849.        at the low 8 bytes of the caller's frame. This way all
  6850.        arguments will reside in one continuous area. */
  6851.     for(i=3+ap->NumArgs-1; i <= 10; ++i)
  6852.       EndPutM32Inc(data, 0x90010000 + (i<<21) + (104+4*(i-3))); /* stw rX,Y(r1) */
  6853.   }
  6854.   else
  6855.   {
  6856.     EndPutM32Inc(data, 0x9421FFA0);                             /* stwu r1,-96(r1) */
  6857.     EndPutM32Inc(data, 0x7D6802A6);                             /* mflr r11 = mfspr r11,8 = get link register */
  6858.     EndPutM32Inc(data, 0x91610064);                             /* stw r11,100(r1) */
  6859.   }
  6860.  
  6861.   for(i = 0; i < ap->NumArgs; ++i)
  6862.   {
  6863.     j = 36+4*ap->Args[i].ArgReg;
  6864.     if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
  6865.     {
  6866.       if(i <= 7)
  6867.       {
  6868.         EndPutM32Inc(data, 0x90010000 + ((i+3)<<21) + j);       /* stw rX,j(r1) */
  6869.       }
  6870.       else
  6871.       {
  6872.         EndPutM32Inc(data, 0x81610000 + (100+(i+1-8)*4));       /* lwz r11,X(r1) = get data from stack */
  6873.         EndPutM32Inc(data, 0x91610000 + j);                     /* stw r11,j(r1) */
  6874.       }
  6875.     }
  6876.     else
  6877.     {
  6878.       EndPutM32Inc(data, 0x39610000 + (100+ap->NumArgs*4));     /* addi r11,r1,X */
  6879.       EndPutM32Inc(data, 0x91610000 + j);                       /* stw r11,X(r1) */
  6880.     }
  6881.   }
  6882.  
  6883.   /* Now place the real function call */
  6884.   EndPutM32Inc(data, 0x39610000 - ap->Bias);                    /* li r11,-(ap->Bias) = addi r11,0,-ap->Bias */
  6885.   EndPutM32Inc(data, 0x91610008);                               /* stw r11,8(r1) */
  6886.   EndPutM32Inc(data, 0x39600001);                               /* li r11,1 = addi r11,0,1 = get IF_CACHEFLUSHALL */
  6887.   EndPutM32Inc(data, 0x9161000C);                               /* stw r11,12(r1) = set M68kCacheMode */
  6888.   EndPutM32Inc(data, 0x91610018);                               /* stw r11,24(r1) = set PPCCacheMode */
  6889.  
  6890.   if(BaseName)
  6891.   {
  6892.     if(Flags & FLAG_SMALLDATA)
  6893.     {
  6894.       j = (data-data3)+2;                                       /* store reloc offset */
  6895.       EndPutM32Inc(data, 0x816D0000);                           /* lwz r11,BaseName@sdarx(r13) */
  6896.     }
  6897.     else
  6898.     {
  6899.       j = (data-data3)+2;                                       /* store reloc offset */
  6900.       EndPutM32Inc(data, 0x3D600000);                           /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
  6901.       EndPutM32Inc(data, 0x816B0000);                           /* lwz r11,BaseName@l(r11) */
  6902.     }
  6903.     EndPutM32Inc(data, 0x9161005C);                             /* stw r11,92(r1) */
  6904.   }
  6905.  
  6906.   EndPutM32Inc(data, 0x38610008);                               /* addi r3,r1,8 */
  6907.   k = (data-data3);                                             /* store reloc offset */
  6908.   EndPutM32Inc(data, 0x48000001);                               /* bl PPCCallOS */
  6909.   if(flags & FUNCFLAG_TAG)                                      /* Varargs. Rebuild the caller's stack-frame. */
  6910.   {
  6911.     EndPutM32Inc(data, 0x81610060);                             /* lwz r11,96(r1) */
  6912.     EndPutM32Inc(data, 0x91610080);                             /* stw r11,128(r1) */
  6913.     EndPutM32Inc(data, 0x81610064);                             /* lwz r11,100(r1) */
  6914.     EndPutM32Inc(data, 0x7D6803A6);                             /* mtlr r11 = mtspr 8,r11 = restore link register */
  6915.     EndPutM32Inc(data, 0x38210080);                             /* addi r1,r1,128 */
  6916.   }
  6917.   else
  6918.   {
  6919.     EndPutM32Inc(data, 0x81610064);                             /* lwz r11,100(r1) */
  6920.     EndPutM32Inc(data, 0x7D6803A6);                             /* mtlr r11 = mtspr 8,r11 = restore link register */
  6921.     EndPutM32Inc(data, 0x38210060);                             /* addi r1,r1,96 */
  6922.   }
  6923.  
  6924.   EndPutM32Inc(data, 0x4E800020);                               /* blr = bclr 20,0 */
  6925.  
  6926.   memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
  6927.   data += 44;  /* 1        9        17         27     33 */
  6928.   
  6929.   EndPutM32(data2, data-tempbuf);                               /* eeh->e_shoff */
  6930.   data2 = data-44;
  6931.  
  6932.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_name */
  6933.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_type */
  6934.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_flags */
  6935.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_addr */
  6936.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_offset */
  6937.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_size */
  6938.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_link */
  6939.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_info */
  6940.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_addralign */
  6941.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_entsize */
  6942.  
  6943.   size = data2-data3;
  6944.   EndPutM32Inc(data, 27);                                       /* esh[1].sh_name = .text */
  6945.   EndPutM32Inc(data, SHT_PROGBITS);                             /* esh[1].sh_type */
  6946.   EndPutM32Inc(data, SHF_ALLOC|SHF_EXECINSTR);                  /* esh[1].sh_flags */
  6947.   EndPutM32Inc(data, 0);                                        /* esh[1].sh_addr */
  6948.   EndPutM32Inc(data, data3-tempbuf);                            /* esh[1].sh_offset */
  6949.   EndPutM32Inc(data, size);                                     /* esh[1].sh_size */
  6950.   EndPutM32Inc(data, 0);                                        /* esh[1].sh_link */
  6951.   EndPutM32Inc(data, 0);                                        /* esh[1].sh_info */
  6952.   EndPutM32Inc(data, 16);                                       /* esh[1].sh_addralign */
  6953.   EndPutM32Inc(data, 0);                                        /* esh[1].sh_entsize */
  6954.  
  6955.   data3 = data;
  6956.   EndPutM32Inc(data, 33);                                       /* esh[2].sh_name = .rela.text */
  6957.   EndPutM32Inc(data, SHT_RELA);                                 /* esh[2].sh_type */
  6958.   EndPutM32Inc(data, 0);                                        /* esh[2].sh_flags */
  6959.   EndPutM32Inc(data, 0);                                        /* esh[2].sh_addr */
  6960.   data += 4;                                                    /* esh[2].sh_offset */
  6961.   data += 4;                                                    /* esh[2].sh_size */
  6962.   EndPutM32Inc(data, 4);                                        /* esh[2].sh_link - the fifth entry is symbol table */
  6963.   EndPutM32Inc(data, 1);                                        /* esh[2].sh_info - the second entry is programm data */
  6964.   EndPutM32Inc(data, 4);                                        /* esh[2].sh_addralign */
  6965.   EndPutM32Inc(data, 12);                                       /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
  6966.  
  6967.   EndPutM32Inc(data, 17);                                       /* esh[3].sh_name = .shstrtab */
  6968.   EndPutM32Inc(data, SHT_STRTAB);                               /* esh[3].sh_type */
  6969.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_flags */
  6970.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_addr */
  6971.   EndPutM32Inc(data, data2-tempbuf);                            /* esh[3].sh_offset */
  6972.   EndPutM32Inc(data, 44);                                       /* esh[3].sh_size */
  6973.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_link */
  6974.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_info */
  6975.   EndPutM32Inc(data, 1);                                        /* esh[3].sh_addralign */
  6976.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_entsize */
  6977.  
  6978.   EndPutM32Inc(data, 1);                                        /* esh[4].sh_name = .symtab */
  6979.   EndPutM32Inc(data, SHT_SYMTAB);                               /* esh[4].sh_type */
  6980.   EndPutM32Inc(data, 0);                                        /* esh[4].sh_flags */
  6981.   EndPutM32Inc(data, 0);                                        /* esh[4].sh_addr */
  6982.   data += 4;                                                    /* esh[4].sh_offset */
  6983.   data += 4;                                                    /* esh[4].sh_size */
  6984.   EndPutM32Inc(data, 5);                                        /* esh[4].sh_link - the sixth entry is our string table */
  6985.   EndPutM32Inc(data, 3);                                        /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
  6986.   EndPutM32Inc(data, 4);                                        /* esh[4].sh_addralign */
  6987.   EndPutM32Inc(data, 16);                                       /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
  6988.  
  6989.   EndPutM32Inc(data, 9);                                        /* esh[0].sh_name = .strtab */
  6990.   EndPutM32Inc(data, SHT_STRTAB);                               /* esh[0].sh_type */
  6991.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_flags */
  6992.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_addr */
  6993.   data += 4;                                                    /* esh[0].sh_offset */
  6994.   data += 4;                                                    /* esh[0].sh_size */
  6995.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_link */
  6996.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_info */
  6997.   EndPutM32Inc(data, 1);                                        /* esh[0].sh_addralign */
  6998.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_entsize */
  6999.  
  7000.   EndPutM32(data3+(2*40)+(4*4), data-tempbuf);                  /* esh[4].sh_offset */
  7001.   EndPutM32(data3+(2*40)+(5*4), BaseName ? 6*16 : 5*16);        /* esh[4].sh_size */
  7002.  
  7003.   data2 = data;
  7004.   data += BaseName ? 6*16 : 5*16;
  7005.  
  7006.   EndPutM32(data3+(3*40)+(4*4), data-tempbuf);                  /* esh[5].sh_offset */
  7007.  
  7008.   i = 0;
  7009.   EndPutM32Inc(data2, i);                                       /* esym[0].st_name */
  7010.   EndPutM32Inc(data2, 0);                                       /* esym[0].st_value */
  7011.   EndPutM32Inc(data2, 0);                                       /* esym[0].st_size */
  7012.   *(data2++) = 0;                                               /* esym[0].st_info */
  7013.   *(data2++) = 0;                                               /* esym[0].st_other */
  7014.   EndPutM16Inc(data2, 0);                                       /* esym[0].st_shndx */
  7015.   data[0] = 0;
  7016.  
  7017.   i += 1;
  7018.   EndPutM32Inc(data2, i);                                       /* esym[1].st_name */
  7019.   EndPutM32Inc(data2, 0);                                       /* esym[1].st_value */
  7020.   EndPutM32Inc(data2, 0);                                       /* esym[1].st_size */
  7021.   *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_FILE);               /* esym[1].st_info */
  7022.   *(data2++) = 0;                                               /* esym[1].st_other */
  7023.   EndPutM16Inc(data2, SHN_ABS);                                 /* esym[1].st_shndx */
  7024.  
  7025.   sprintf((strptr)data+i, "%s.s", name); while(data[i++]) ; /* get next store space */
  7026.   EndPutM32Inc(data2, 0);                                       /* esym[2].st_name */
  7027.   EndPutM32Inc(data2, 0);                                       /* esym[2].st_value */
  7028.   EndPutM32Inc(data2, 0);                                       /* esym[2].st_size */
  7029.   *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_SECTION);            /* esym[2].st_info */
  7030.   *(data2++) = 0;                                               /* esym[2].st_other */
  7031.   EndPutM16Inc(data2, 1);                                       /* esym[2].st_shndx - the second entry is program section! */
  7032.  
  7033.   EndPutM32Inc(data2, i);                                       /* esym[3].st_name */
  7034.   EndPutM32Inc(data2, 0);                                       /* esym[3].st_value */
  7035.   EndPutM32Inc(data2, size);                                    /* esym[3].st_size */
  7036.   *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_FUNC);              /* esym[3].st_info */
  7037.   *(data2++) = 0;                                               /* esym[3].st_other */
  7038.   EndPutM16Inc(data2, 1);                                       /* esym[3].st_shndx - the second entry is program section! */
  7039.  
  7040.   sprintf((strptr)data+i, name); while(data[i++]) ; /* get next store space */
  7041.   EndPutM32Inc(data2, i);                                       /* esym[4].st_name */
  7042.   EndPutM32Inc(data2, 0);                                       /* esym[4].st_value */
  7043.   EndPutM32Inc(data2, 0);                                       /* esym[4].st_size */
  7044.   *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE);            /* esym[4].st_info */
  7045.   *(data2++) = 0;                                               /* esym[4].st_other */
  7046.   EndPutM16Inc(data2, 0);                                       /* esym[4].st_shndx */
  7047.  
  7048.   sprintf((strptr)data+i, "PPCCallOS"); while(data[i++]) ; /* get next store space */
  7049.   if(BaseName)
  7050.   {
  7051.     EndPutM32Inc(data2, i);                                     /* esym[5].st_name */
  7052.     EndPutM32Inc(data2, 0);                                     /* esym[5].st_value */
  7053.     EndPutM32Inc(data2, 0);                                     /* esym[5].st_size */
  7054.     *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE);          /* esym[5].st_info */
  7055.     *(data2++) = 0;                                             /* esym[5].st_other */
  7056.     EndPutM16/*Inc*/(data2, 0);                                 /* esym[5].st_shndx */
  7057.  
  7058.     sprintf((strptr)data+i, BaseName); while(data[i++]) ; /* get next store space */
  7059.   }
  7060.   EndPutM32(data3+(3*40)+(5*4), i);                             /* esh[5].sh_size */
  7061.   while(i&3) /* long aligned */
  7062.    data[i++] = 0;
  7063.   data += i;
  7064.  
  7065.   EndPutM32(data3+(4*4), data-tempbuf);                         /* esh[2].sh_offset */
  7066.  
  7067.   data2 = data;
  7068.  
  7069.   EndPutM32Inc(data, k);                                        /* erel[0].r_offset */
  7070.   EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_REL24));              /* erel[0].r_info - entry 4, type 10 */
  7071.   EndPutM32Inc(data, 0);                                        /* erel[0].r_addend */
  7072.  
  7073.   if(BaseName)
  7074.   {
  7075.     if(Flags & FLAG_SMALLDATA)
  7076.     {
  7077.       EndPutM32Inc(data, j);                                    /* erel[1].r_offset */
  7078.       EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_SDAREL16));       /* erel[1].r_info - entry 5, type 32 */
  7079.       EndPutM32Inc(data, 0);                                    /* erel[1].r_addend */
  7080.     }
  7081.     else
  7082.     {
  7083.       EndPutM32Inc(data, j);                                    /* erel[1].r_offset */
  7084.       EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_ADDR16_HA));      /* erel[1].r_info - entry 5, type 6 */
  7085.       EndPutM32Inc(data, 0);                                    /* erel[1].r_addend */
  7086.       EndPutM32Inc(data, j+4);                                  /* erel[2].r_offset */
  7087.       EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_ADDR16_LO));      /* erel[2].r_info - entry 5, type 4 */
  7088.       EndPutM32Inc(data, 0);                                    /* erel[2].r_addend */
  7089.     }
  7090.   }
  7091.   EndPutM32(data3+(5*4), data-data2);                           /* esh[2].sh_size */
  7092.  
  7093.   /* make ar header and store all */
  7094.   arh = (struct ArHeader *) (data+20);
  7095.   memset(arh, ' ', sizeof(struct ArHeader));
  7096.  
  7097.   arh->ar_time[sprintf(arh->ar_time, "%lu", (uint32) time(0))] = ' ';
  7098.   arh->ar_uid[0] = arh->ar_gid[0] = arh->ar_mode[1] =
  7099.   arh->ar_mode[2] = '0';
  7100.   arh->ar_mode[0] = '6';
  7101.   arh->ar_fmag[0] = 96;
  7102.   arh->ar_fmag[1] = '\n';
  7103.  
  7104.   if((k = strlen(name) + 2) >= 16)
  7105.   {
  7106.     arh->ar_name[sprintf(arh->ar_name, "#1/%ld", k)] = ' ';
  7107.   }
  7108.   else
  7109.   {
  7110.     k = 0;
  7111.     arh->ar_name[sprintf(arh->ar_name, "%s.o", name)] = ' ';
  7112.   }
  7113.  
  7114.   j = k + (data-tempbuf);
  7115.   for(i = 9; j; --i) /* make decimal number */
  7116.   {
  7117.     data[i] = (j%10)+'0';
  7118.     j /= 10;
  7119.   }
  7120.   for(j = 0; i < 9; ++j)
  7121.     arh->ar_size[j] = data[++i];
  7122.   
  7123.   DoOutputDirect(arh, sizeof(struct ArHeader));
  7124.  
  7125.   if(k)
  7126.   {
  7127.     DoOutput("%s.o", name);
  7128.     if(k & 1)
  7129.       *(data++) = 0x0A; /* alignment byte! */
  7130.   }
  7131.  
  7132.   return DoOutputDirect(tempbuf, data-tempbuf);
  7133. }
  7134.  
  7135. uint32 FuncVBCCMorphText(struct AmiPragma *ap, uint32 flags, strptr name)
  7136. {
  7137.   int32 i, nrcopyar = 0, stcksize = 16;
  7138.  
  7139.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
  7140.     return 1;
  7141.  
  7142.   Flags |= FLAG_DONE;
  7143.  
  7144.   if(Flags & FLAG_SINGLEFILE)
  7145.   {
  7146.     if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  7147.  
  7148.     if(HEADER)
  7149.     {
  7150.       DoOutput("\n");
  7151.       DoOutputDirect(HEADER, headersize);
  7152.     }
  7153.   }
  7154.  
  7155.   if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
  7156.     DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
  7157.  
  7158.   if(Flags & FLAG_SINGLEFILE)
  7159.     DoOutput("\t.file\t\"%s.s\"\n", name);
  7160.   if(BaseName)
  7161.     DoOutput("\t.global %s\n", BaseName);
  7162.   DoOutput("\t.global %s\n\t.align\t4\n%s:\n",name, name);
  7163.  
  7164.   if(flags & FUNCFLAG_TAG)
  7165.   {
  7166.     nrcopyar = ap->NumArgs > 8 ? 0 : 8 + 1 - ap->NumArgs;
  7167.     stcksize = (((nrcopyar + 2 + 3)&(~3))-nrcopyar)*4;
  7168.   }
  7169.  
  7170.   DoOutput("\tstwu\t%s1,-%d(%s1)\n"
  7171.            "\tmflr\t%s0\n",
  7172.   PPCRegPrefix, stcksize+nrcopyar*4, PPCRegPrefix, PPCRegPrefix);
  7173.  
  7174.   if(nrcopyar)
  7175.   {
  7176.     /* Hack the stack-frame for varargs.
  7177.        Build stack-frame, but save LR in our own stack-frame,
  7178.        because we have to overwrite the lower 8 bytes of the
  7179.        caller's frame. */
  7180.     /* Save the caller's saved SP in our own stack-frame. */
  7181.     DoOutput("\tlwz\t%s11,%d(%s1)\n\tstw\t%s11,%d(%s1)\n", PPCRegPrefix,
  7182.     stcksize+nrcopyar*4, PPCRegPrefix, PPCRegPrefix, stcksize, PPCRegPrefix);
  7183.  
  7184.     /* Store r3-r8 at the top of our stack-frame and r9-r10
  7185.        at the low 8 bytes of the caller's frame. This way all
  7186.        arguments will reside in one continuous area.
  7187.        Only copy the really relevant parts. */
  7188.     for(i = 10; i > 10-nrcopyar; --i)
  7189.       DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i,
  7190.       stcksize+4*(i-1+nrcopyar-8),PPCRegPrefix);
  7191.   }
  7192.  
  7193.   if(BaseName)
  7194.   {
  7195.     if(Flags & FLAG_SMALLDATA)
  7196.       DoOutput("\tlwz\t%s12,%s@sdarx(%s13)\n", PPCRegPrefix, BaseName, PPCRegPrefix);
  7197.     else
  7198.       DoOutput("\tlis\t%s12,%s@ha\n\tlwz\t%s12,%s@l(%s12)\n", PPCRegPrefix,
  7199.       BaseName, PPCRegPrefix, BaseName, PPCRegPrefix);
  7200.   }
  7201.  
  7202.   DoOutput("\tstw\t%s0,%d(%s1)\n", PPCRegPrefix, stcksize+4, PPCRegPrefix);
  7203.  
  7204.   for(i = 0; i < ap->NumArgs; ++i)
  7205.   {
  7206.     if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
  7207.     {
  7208.       if(i <= 7)
  7209.         DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3);
  7210.       else
  7211.         DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix,
  7212.         stcksize+(i+2-8)*4, PPCRegPrefix, PPCRegPrefix);
  7213.     }
  7214.     else
  7215.       DoOutput("\taddi\t%s4,%s1,%d\n\tstw\t%s4,", PPCRegPrefix,
  7216.       PPCRegPrefix, stcksize+8+(ap->NumArgs > 8 ? (ap->NumArgs-8)*4 : 0),
  7217.       PPCRegPrefix);
  7218.     DoOutput("%d(%s2)\n", 4*ap->Args[i].ArgReg, PPCRegPrefix);
  7219.   }
  7220.  
  7221.   DoOutput("\tlwz\t%s11,100(%s2)\n",         /* EmulCallDirectOS */
  7222.            PPCRegPrefix, PPCRegPrefix);
  7223.  
  7224.   if(BaseName)
  7225.     DoOutput("\tstw\t%s12,56(%s2)\n", PPCRegPrefix, PPCRegPrefix); /* store basepointer in A6 */
  7226.  
  7227.   /* Now place the real function call */
  7228.   DoOutput("\tli\t%s3,-%d\n", /* store offset in EmulHandle */
  7229.   PPCRegPrefix, ap->Bias);
  7230.  
  7231.   DoOutput("\tmtlr\t%s11\n\tblrl\n", PPCRegPrefix);
  7232.  
  7233.   if(flags & FUNCFLAG_TAG) /* Varargs. Rebuild the caller's stack-frame. */
  7234.   {
  7235.     DoOutput("\tlwz\t%s11,%d(%s1)\n\tstw\t%s11,%d(%s1)\n",
  7236.     PPCRegPrefix, stcksize, PPCRegPrefix, PPCRegPrefix,
  7237.     stcksize+4+nrcopyar*4,PPCRegPrefix);
  7238.   }
  7239.  
  7240.   DoOutput("\tlwz\t%s0,%d(%s1)\n"
  7241.            "\taddi\t%s1,%s1,%d\n"
  7242.            "\tmtlr\t%s0\n",
  7243.   PPCRegPrefix, stcksize+4,PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
  7244.   stcksize+nrcopyar*4, PPCRegPrefix);
  7245.  
  7246.   return DoOutput("\tblr\n\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n", name, name, name);
  7247. }
  7248.  
  7249. uint32 FuncVBCCMorphCode(struct AmiPragma *ap, uint32 flags, strptr name)
  7250. {
  7251.   int32 i, j, k=0, size, nrcopyar = 0, stcksize = 16;
  7252.   uint8 *data, *data2, *data3;
  7253.   struct ArHeader *arh;
  7254.  
  7255.   data = tempbuf;
  7256.  
  7257.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
  7258.     return 1;
  7259.  
  7260.   Flags |= FLAG_DONE;
  7261.  
  7262.   *(data++) = 0x7F;                                             /* eeh->e_ident[EI_MAG0] */
  7263.   *(data++) = 'E';                                              /* eeh->e_ident[EI_MAG1] */
  7264.   *(data++) = 'L';                                              /* eeh->e_ident[EI_MAG2] */
  7265.   *(data++) = 'F';                                              /* eeh->e_ident[EI_MAG3] */
  7266.   *(data++) = ELFCLASS32;                                       /* eeh->e_ident[EI_CLASS] */
  7267.   *(data++) = ELFDATA2MSB;                                      /* eeh->e_ident[EI_DATA] */
  7268.   *(data++) = EV_CURRENT;                                       /* eeh->e_ident[EI_VERSION] */
  7269.   *(data++) = 0; *(data++) = 0; *(data++) = 0;
  7270.   *(data++) = 0; *(data++) = 0; *(data++) = 0;
  7271.   *(data++) = 0; *(data++) = 0; *(data++) = 0;
  7272.   EndPutM16Inc(data, ET_REL);                                   /* eeh->e_type */
  7273.   EndPutM16Inc(data, EM_POWERPC);                               /* eeh->e_machine */
  7274.   EndPutM32Inc(data, EV_CURRENT);                               /* eeh->e_version */
  7275.   EndPutM32Inc(data, 0);                                        /* eeh->e_entry */
  7276.   EndPutM32Inc(data, 0);                                        /* eeh->e_phoff */
  7277.   data2 = data; data += 4;
  7278.   EndPutM32Inc(data, 0);                                        /* eeh->e_flags */
  7279.   EndPutM16Inc(data, 52);                                       /* eeh->e_ehsize */
  7280.   EndPutM16Inc(data, 0);                                        /* eeh->e_phentsize */
  7281.   EndPutM16Inc(data, 0);                                        /* eeh->e_phnum */
  7282.   EndPutM16Inc(data, 40);                                       /* eeh->e_shentsize */
  7283.   EndPutM16Inc(data, 6);                                        /* eeh->e_shnum */
  7284.   EndPutM16Inc(data, 3);                                        /* eeh->e_shstrndx - fourth table is string table */
  7285.  
  7286.   data3 = data;
  7287.  
  7288.   if(flags & FUNCFLAG_TAG)
  7289.   {
  7290.     nrcopyar = ap->NumArgs > 8 ? 0 : 8 + 1 - ap->NumArgs;
  7291.     stcksize = (((nrcopyar + 2 + 3)&(~3))-nrcopyar)*4;
  7292.   }
  7293.  
  7294.   EndPutM32Inc(data, 0x94210000+0x10000-(stcksize+nrcopyar*4)); /* stwu r1,-%d(r1) */
  7295.   EndPutM32Inc(data, 0x7C0802A6);                               /* mflr r0 = mfspr r0,8 = get link register */
  7296.  
  7297.   if(nrcopyar)
  7298.   {
  7299.     /* Hack the stack-frame for varargs.
  7300.        Build stack-frame, but save LR in our own stack-frame,
  7301.        because we have to overwrite the lower 8 bytes of the
  7302.        caller's frame. */
  7303.     /* Save the caller's saved SP in our own stack-frame. */
  7304.     EndPutM32Inc(data, 0x81610000+stcksize+nrcopyar*4);         /* lwz r11,%d(r1) */
  7305.     EndPutM32Inc(data, 0x91610000+stcksize);                    /* stw r11,%d(r1) */
  7306.  
  7307.     /* Store r3-r8 at the top of our stack-frame and r9-r10
  7308.        at the low 8 bytes of the caller's frame. This way all
  7309.        arguments will reside in one continuous area.
  7310.        Only copy the really relevant parts. */
  7311.     for(i = 10; i > 10-nrcopyar; --i)
  7312.       EndPutM32Inc(data, 0x90010000 + (i<<21) + (stcksize+4*(i-1+nrcopyar-8))); /* stw rX,Y(r1) */
  7313.   }
  7314.  
  7315.   if(BaseName)
  7316.   {
  7317.     if(Flags & FLAG_SMALLDATA)
  7318.     {
  7319.       k = (data-data3)+2;                                       /* store reloc offset */
  7320.       EndPutM32Inc(data, 0x818D0000);                           /* lwz r12,BaseName@sdarx(r13) */
  7321.     }
  7322.     else
  7323.     {
  7324.       k = (data-data3)+2;                                       /* store reloc offset */
  7325.       EndPutM32Inc(data, 0x3D800000);                           /* lis r12,BaseName@ha = addis r12,0,BaseName@ha */
  7326.       EndPutM32Inc(data, 0x818C0000);                           /* lwz r12,BaseName@l(r12) */
  7327.     }
  7328.   }
  7329.  
  7330.   EndPutM32Inc(data, 0x90010000+stcksize+4);                    /* stw r0,%d(r1) */
  7331.  
  7332.   for(i = 0; i < ap->NumArgs; ++i)
  7333.   {
  7334.     j = 4*ap->Args[i].ArgReg;
  7335.     if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
  7336.     {
  7337.       if(i <= 7)
  7338.       {
  7339.         EndPutM32Inc(data, 0x90020000 + ((i+3)<<21) + j);       /* stw rX,j(r2) */
  7340.       }
  7341.       else
  7342.       {
  7343.         EndPutM32Inc(data, 0x81610000 + (stcksize+(i+2-8)*4));  /* lwz r11,X(r1) = get data from stack */
  7344.         EndPutM32Inc(data, 0x91620000 + j);                     /* stw r11,j(r1) */
  7345.       }
  7346.     }
  7347.     else
  7348.     {
  7349.       EndPutM32Inc(data, 0x38810000 + (stcksize+8+(ap->NumArgs > 8 ? (ap->NumArgs-8)*4 : 0))); /* addi r4,r1,X */
  7350.       EndPutM32Inc(data, 0x90820000 + j);                       /* stw r4,X(r2) */
  7351.     }
  7352.   }
  7353.  
  7354.   EndPutM32Inc(data, 0x81620064);                               /* lwz r11,100(r2) */
  7355.  
  7356.   if(BaseName)
  7357.     EndPutM32Inc(data, 0x91820038);                             /* stw r12,56(r2) */
  7358.  
  7359.   /* Now place the real function call */
  7360.   EndPutM32Inc(data, 0x38600000 + 0x10000 - ap->Bias);          /* li r3,-(ap->Bias) = addi r3,0,-ap->Bias */
  7361.  
  7362.   EndPutM32Inc(data, 0x7D6803A6);                               /* mtlr r11 = mtspr 8,r11 = restore link register */
  7363.   EndPutM32Inc(data, 0x4E800021);                               /* blrl = bclrl 20,0 */
  7364.  
  7365.   if(flags & FUNCFLAG_TAG) /* Varargs. Rebuild the caller's stack-frame. */
  7366.   {
  7367.     EndPutM32Inc(data, 0x81610000 + stcksize);                  /* lwz r11,X(r1) */
  7368.     EndPutM32Inc(data, 0x91610000 + (stcksize+4+nrcopyar*4));   /* stw r11,Y(r1) */
  7369.   }
  7370.  
  7371.   EndPutM32Inc(data, 0x80010000 + stcksize+4);                  /* lwz r0,X(r1) */
  7372.   EndPutM32Inc(data, 0x38210000 + (stcksize+nrcopyar*4));       /* addi r1,r1,Y */
  7373.   EndPutM32Inc(data, 0x7C0803A6);                               /* mtlr r0 = mtspr 8,r0 = restore link register */
  7374.  
  7375.   EndPutM32Inc(data, 0x4E800020);                               /* blr = bclr 20,0 */
  7376.  
  7377.   memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
  7378.   data += 44;  /* 1        9        17         27     33 */
  7379.   
  7380.   EndPutM32(data2, data-tempbuf);                               /* eeh->e_shoff */
  7381.   data2 = data-44;
  7382.  
  7383.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_name */
  7384.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_type */
  7385.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_flags */
  7386.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_addr */
  7387.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_offset */
  7388.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_size */
  7389.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_link */
  7390.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_info */
  7391.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_addralign */
  7392.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_entsize */
  7393.  
  7394.   size = data2-data3;
  7395.   EndPutM32Inc(data, 27);                                       /* esh[1].sh_name = .text */
  7396.   EndPutM32Inc(data, SHT_PROGBITS);                             /* esh[1].sh_type */
  7397.   EndPutM32Inc(data, SHF_ALLOC|SHF_EXECINSTR);                  /* esh[1].sh_flags */
  7398.   EndPutM32Inc(data, 0);                                        /* esh[1].sh_addr */
  7399.   EndPutM32Inc(data, data3-tempbuf);                            /* esh[1].sh_offset */
  7400.   EndPutM32Inc(data, size);                                     /* esh[1].sh_size */
  7401.   EndPutM32Inc(data, 0);                                        /* esh[1].sh_link */
  7402.   EndPutM32Inc(data, 0);                                        /* esh[1].sh_info */
  7403.   EndPutM32Inc(data, 16);                                       /* esh[1].sh_addralign */
  7404.   EndPutM32Inc(data, 0);                                        /* esh[1].sh_entsize */
  7405.  
  7406.   data3 = data;
  7407.   EndPutM32Inc(data, 33);                                       /* esh[2].sh_name = .rela.text */
  7408.   EndPutM32Inc(data, SHT_RELA);                                 /* esh[2].sh_type */
  7409.   EndPutM32Inc(data, 0);                                        /* esh[2].sh_flags */
  7410.   EndPutM32Inc(data, 0);                                        /* esh[2].sh_addr */
  7411.   data += 4;                                                    /* esh[2].sh_offset */
  7412.   data += 4;                                                    /* esh[2].sh_size */
  7413.   EndPutM32Inc(data, 4);                                        /* esh[2].sh_link - the fifth entry is symbol table */
  7414.   EndPutM32Inc(data, 1);                                        /* esh[2].sh_info - the second entry is programm data */
  7415.   EndPutM32Inc(data, 4);                                        /* esh[2].sh_addralign */
  7416.   EndPutM32Inc(data, 12);                                       /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
  7417.  
  7418.   EndPutM32Inc(data, 17);                                       /* esh[3].sh_name = .shstrtab */
  7419.   EndPutM32Inc(data, SHT_STRTAB);                               /* esh[3].sh_type */
  7420.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_flags */
  7421.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_addr */
  7422.   EndPutM32Inc(data, data2-tempbuf);                            /* esh[3].sh_offset */
  7423.   EndPutM32Inc(data, 44);                                       /* esh[3].sh_size */
  7424.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_link */
  7425.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_info */
  7426.   EndPutM32Inc(data, 1);                                        /* esh[3].sh_addralign */
  7427.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_entsize */
  7428.  
  7429.   EndPutM32Inc(data, 1);                                        /* esh[4].sh_name = .symtab */
  7430.   EndPutM32Inc(data, SHT_SYMTAB);                               /* esh[4].sh_type */
  7431.   EndPutM32Inc(data, 0);                                        /* esh[4].sh_flags */
  7432.   EndPutM32Inc(data, 0);                                        /* esh[4].sh_addr */
  7433.   data += 4;                                                    /* esh[4].sh_offset */
  7434.   data += 4;                                                    /* esh[4].sh_size */
  7435.   EndPutM32Inc(data, 5);                                        /* esh[4].sh_link - the sixth entry is our string table */
  7436.   EndPutM32Inc(data, 3);                                        /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
  7437.   EndPutM32Inc(data, 4);                                        /* esh[4].sh_addralign */
  7438.   EndPutM32Inc(data, 16);                                       /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
  7439.  
  7440.   EndPutM32Inc(data, 9);                                        /* esh[0].sh_name = .strtab */
  7441.   EndPutM32Inc(data, SHT_STRTAB);                               /* esh[0].sh_type */
  7442.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_flags */
  7443.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_addr */
  7444.   data += 4;                                                    /* esh[0].sh_offset */
  7445.   data += 4;                                                    /* esh[0].sh_size */
  7446.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_link */
  7447.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_info */
  7448.   EndPutM32Inc(data, 1);                                        /* esh[0].sh_addralign */
  7449.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_entsize */
  7450.  
  7451.   EndPutM32(data3+(2*40)+(4*4), data-tempbuf);                  /* esh[4].sh_offset */
  7452.   EndPutM32(data3+(2*40)+(5*4), BaseName ? 5*16 : 4*16);        /* esh[4].sh_size */
  7453.  
  7454.   data2 = data;
  7455.   data += BaseName ? 5*16 : 4*16;
  7456.  
  7457.   EndPutM32(data3+(3*40)+(4*4), data-tempbuf);                  /* esh[5].sh_offset */
  7458.  
  7459.   i = 0;
  7460.   EndPutM32Inc(data2, i);                                       /* esym[0].st_name */
  7461.   EndPutM32Inc(data2, 0);                                       /* esym[0].st_value */
  7462.   EndPutM32Inc(data2, 0);                                       /* esym[0].st_size */
  7463.   *(data2++) = 0;                                               /* esym[0].st_info */
  7464.   *(data2++) = 0;                                               /* esym[0].st_other */
  7465.   EndPutM16Inc(data2, 0);                                       /* esym[0].st_shndx */
  7466.   data[0] = 0;
  7467.  
  7468.   i += 1;
  7469.   EndPutM32Inc(data2, i);                                       /* esym[1].st_name */
  7470.   EndPutM32Inc(data2, 0);                                       /* esym[1].st_value */
  7471.   EndPutM32Inc(data2, 0);                                       /* esym[1].st_size */
  7472.   *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_FILE);               /* esym[1].st_info */
  7473.   *(data2++) = 0;                                               /* esym[1].st_other */
  7474.   EndPutM16Inc(data2, SHN_ABS);                                 /* esym[1].st_shndx */
  7475.  
  7476.   sprintf((strptr)data+i, "%s.s", name); while(data[i++]) ; /* get next store space */
  7477.   EndPutM32Inc(data2, 0);                                       /* esym[2].st_name */
  7478.   EndPutM32Inc(data2, 0);                                       /* esym[2].st_value */
  7479.   EndPutM32Inc(data2, 0);                                       /* esym[2].st_size */
  7480.   *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_SECTION);            /* esym[2].st_info */
  7481.   *(data2++) = 0;                                               /* esym[2].st_other */
  7482.   EndPutM16Inc(data2, 1);                                       /* esym[2].st_shndx - the second entry is program section! */
  7483.  
  7484.   EndPutM32Inc(data2, i);                                       /* esym[3].st_name */
  7485.   EndPutM32Inc(data2, 0);                                       /* esym[3].st_value */
  7486.   EndPutM32Inc(data2, size);                                    /* esym[3].st_size */
  7487.   *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_FUNC);              /* esym[3].st_info */
  7488.   *(data2++) = 0;                                               /* esym[3].st_other */
  7489.   EndPutM16Inc(data2, 1);                                       /* esym[3].st_shndx - the second entry is program section! */
  7490.  
  7491.   sprintf((strptr)data+i, name); while(data[i++]) ; /* get next store space */
  7492.   if(BaseName)
  7493.   {
  7494.     EndPutM32Inc(data2, i);                                     /* esym[4].st_name */
  7495.     EndPutM32Inc(data2, 0);                                     /* esym[4].st_value */
  7496.     EndPutM32Inc(data2, 0);                                     /* esym[4].st_size */
  7497.     *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE);          /* esym[4].st_info */
  7498.     *(data2++) = 0;                                             /* esym[4].st_other */
  7499.     EndPutM16/*Inc*/(data2, 0);                                 /* esym[4].st_shndx */
  7500.  
  7501.     sprintf((strptr)data+i, BaseName); while(data[i++]) ; /* get next store space */
  7502.   }
  7503.   EndPutM32(data3+(3*40)+(5*4), i);                             /* esh[5].sh_size */
  7504.   while(i&3) /* long aligned */
  7505.    data[i++] = 0;
  7506.   data += i;
  7507.  
  7508.   EndPutM32(data3+(4*4), data-tempbuf);                         /* esh[2].sh_offset */
  7509.  
  7510.   data2 = data;
  7511.  
  7512.   if(BaseName)
  7513.   {
  7514.     if(Flags & FLAG_SMALLDATA)
  7515.     {
  7516.       EndPutM32Inc(data, k);                                    /* erel[0].r_offset */
  7517.       EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_SDAREL16));       /* erel[0].r_info - entry 4, type 32 */
  7518.       EndPutM32Inc(data, 0);                                    /* erel[0].r_addend */
  7519.     }
  7520.     else
  7521.     {
  7522.       EndPutM32Inc(data, k);                                    /* erel[0].r_offset */
  7523.       EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_ADDR16_HA));      /* erel[0].r_info - entry 4, type 6 */
  7524.       EndPutM32Inc(data, 0);                                    /* erel[0].r_addend */
  7525.       EndPutM32Inc(data, k+4);                                  /* erel[1].r_offset */
  7526.       EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_ADDR16_LO));      /* erel[1].r_info - entry 4, type 4 */
  7527.       EndPutM32Inc(data, 0);                                    /* erel[1].r_addend */
  7528.     }
  7529.   }
  7530.   EndPutM32(data3+(5*4), data-data2);                           /* esh[2].sh_size */
  7531.  
  7532.   /* make ar header and store all */
  7533.   arh = (struct ArHeader *) (data+20);
  7534.   memset(arh, ' ', sizeof(struct ArHeader));
  7535.  
  7536.   arh->ar_time[sprintf(arh->ar_time, "%lu", (uint32) time(0))] = ' ';
  7537.   arh->ar_uid[0] = arh->ar_gid[0] = arh->ar_mode[1] =
  7538.   arh->ar_mode[2] = '0';
  7539.   arh->ar_mode[0] = '6';
  7540.   arh->ar_fmag[0] = 96;
  7541.   arh->ar_fmag[1] = '\n';
  7542.  
  7543.   if((k = strlen(name) + 2) >= 16)
  7544.   {
  7545.     arh->ar_name[sprintf(arh->ar_name, "#1/%ld", k)] = ' ';
  7546.   }
  7547.   else
  7548.   {
  7549.     k = 0;
  7550.     arh->ar_name[sprintf(arh->ar_name, "%s.o", name)] = ' ';
  7551.   }
  7552.  
  7553.   j = k + (data-tempbuf);
  7554.   for(i = 9; j; --i) /* make decimal number */
  7555.   {
  7556.     data[i] = (j%10)+'0';
  7557.     j /= 10;
  7558.   }
  7559.   for(j = 0; i < 9; ++j)
  7560.     arh->ar_size[j] = data[++i];
  7561.   
  7562.   DoOutputDirect(arh, sizeof(struct ArHeader));
  7563.  
  7564.   if(k)
  7565.   {
  7566.     DoOutput("%s.o", name);
  7567.     if(k & 1)
  7568.       *(data++) = 0x0A; /* alignment byte! */
  7569.   }
  7570.  
  7571.   return DoOutputDirect(tempbuf, data-tempbuf);
  7572. }
  7573.  
  7574. uint32 FuncEModule(struct AmiPragma *ap, uint32 flags, strptr name)
  7575. {
  7576.   uint8 i, r;
  7577.  
  7578.   if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_A6USE|AMIPRAGFLAG_PPC) ||
  7579.   (flags & FUNCFLAG_ALIAS))
  7580.     return 1;
  7581.  
  7582.   if(LastBias >= ap->Bias)
  7583.     DoError(ERR_ILLEGAL_FUNCTION_POSITION, ap->Line, name);
  7584.   else
  7585.   {
  7586.     Flags |= FLAG_DONE; /* We did something */
  7587.  
  7588.     for(LastBias += BIAS_OFFSET; LastBias < ap->Bias; LastBias += BIAS_OFFSET)
  7589.       DoOutputDirect("Dum\x10", 4);
  7590.  
  7591.     DoOutput("%c", toupper(name[0]));
  7592.     if(name[1])
  7593.     {
  7594.       DoOutput("%c", tolower(name[1]));
  7595.       if(name[2])
  7596.         DoOutput("%s", name+2);
  7597.     }
  7598.     if(!ap->NumArgs)
  7599.       DoOutputDirect("\x10", 1);
  7600.     else
  7601.     {
  7602.       for(i = 0; i < ap->NumArgs; ++i)
  7603.       {
  7604.         r = ap->Args[i].ArgReg;
  7605.         DoOutputDirect(&r, 1);
  7606.       }
  7607.     }
  7608.   }
  7609.   return 1;
  7610. }
  7611.  
  7612. uint32 FuncFD(struct AmiPragma *ap, uint32 flags, strptr name)
  7613. {
  7614.   int32 i;
  7615.  
  7616.   Flags |= FLAG_DONE; /* We did something */
  7617.  
  7618.   if(ap->Flags & AMIPRAGFLAG_PUBLIC)
  7619.   {
  7620.     if(Flags & FLAG_ISPRIVATE)
  7621.     {
  7622.       Flags ^= FLAG_ISPRIVATE;
  7623.       DoOutput("##public\n");
  7624.     }
  7625.   }
  7626.   else
  7627.   {
  7628.     if(!(Flags & FLAG_ISPRIVATE))
  7629.       DoOutput("##private\n");
  7630.     Flags |= FLAG_ISPRIVATE;
  7631.   }
  7632.  
  7633.   LastBias += BIAS_OFFSET;
  7634.   if(LastBias != ap->Bias)
  7635.   {
  7636.     DoOutput("##bias %d\n", ap->Bias);
  7637.     LastBias = ap->Bias;
  7638.   }
  7639.  
  7640.   if(ap->Abi != CurrentABI)
  7641.   {
  7642.     switch(ap->Abi)
  7643.     {
  7644.     case ABI_M68K: DoOutput("##abi M68k\n"); break;
  7645.     case ABI_PPC0: DoOutput("##abi PPC0\n"); break;
  7646.     case ABI_PPC2: DoOutput("##abi PPC2\n"); break;
  7647.     case ABI_PPC:  DoOutput("##abi PPC\n"); break;
  7648.     }
  7649.     CurrentABI = ap->Abi;
  7650.   }
  7651.  
  7652.   DoOutput("%s("/*)*/, name);
  7653.   for(i = 0; i < ap->CallArgs; i++)
  7654.     DoOutput("%s%s", ap->Args[i].ArgName, i < ap->CallArgs-1 ? "," : "");
  7655.   DoOutput(/*(*/")("/*)*/);
  7656.  
  7657.   if(!(ap->Flags & AMIPRAGFLAG_PPC))
  7658.   {
  7659.     for(i = 0; i < ap->CallArgs; i++)
  7660.     {
  7661.       DoOutput("%s%s", RegNames[ap->Args[i].ArgReg], i < ap->CallArgs-1 ? 
  7662.       (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg ? "/" : ",") : "");
  7663.     }
  7664.   }
  7665.   return DoOutput(/*(*/")\n");
  7666. }
  7667.  
  7668. /* called from FuncSFD directly */
  7669. uint32 FuncClib(struct AmiPragma *ap, uint32 flags, strptr name)
  7670. {
  7671.   struct ClibData *cd;
  7672.   int32 i, s, c;
  7673.  
  7674.   Flags |= FLAG_DONE; /* We did something */
  7675.  
  7676.   if(!(cd = GetClibFunc(name, ap, flags)))
  7677.     return 1;
  7678.  
  7679.   s = MakeClibType(tempbuf, &cd->ReturnType, 0);
  7680.   DoOutputDirect(tempbuf, s);
  7681.   DoOutput(" %s("/*)*/, name);
  7682.  
  7683.   if(ap->NumArgs)
  7684.   {
  7685.     for(i = 0; i < cd->NumArgs; i++)
  7686.     {
  7687.       c = MakeClibType(tempbuf, &cd->Args[i], ap->Args[i].ArgName);
  7688.       if(s+c+2 > 75 && s)
  7689.       {
  7690.         DoOutput(i ? ",\n\t" : "\n\t"); s = 8;
  7691.       }
  7692.       else if(i)
  7693.       {
  7694.         DoOutput(", "); s += 2;
  7695.       }
  7696.       DoOutputDirect(tempbuf, c);
  7697.       s += c;
  7698.     }
  7699.   }
  7700.   else if(Flags2 & FLAG2_CLIBOUT)
  7701.     DoOutput("void");
  7702.   return DoOutput(/*(*/")%s", Flags2 & FLAG2_CLIBOUT ? ";\n" : "");
  7703. }
  7704.  
  7705. uint32 FuncSFD(struct AmiPragma *ap, uint32 flags, strptr name)
  7706. {
  7707.   struct ClibData *cd;
  7708.   int32 i, j;
  7709.  
  7710.   if(!(cd = GetClibFunc(name, ap, flags)))
  7711.     return 1;
  7712.  
  7713.   if(ap->Flags & AMIPRAGFLAG_PUBLIC)
  7714.   {
  7715.     if(Flags & FLAG_ISPRIVATE)
  7716.     {
  7717.       Flags ^= FLAG_ISPRIVATE;
  7718.       DoOutput("==public\n");
  7719.     }
  7720.   }
  7721.   else
  7722.   {
  7723.     if(!(Flags & FLAG_ISPRIVATE))
  7724.       DoOutput("==private\n");
  7725.     Flags |= FLAG_ISPRIVATE;
  7726.   }
  7727.  
  7728.   if(ap->Abi != CurrentABI)
  7729.   {
  7730.     switch(ap->Abi)
  7731.     {
  7732.     case ABI_M68K: DoOutput("==abi M68k\n"); break;
  7733.     case ABI_PPC0: DoOutput("==abi PPC0\n"); break;
  7734.     case ABI_PPC2: DoOutput("==abi PPC2\n"); break;
  7735.     case ABI_PPC:  DoOutput("==abi PPC\n"); break;
  7736.     }
  7737.     CurrentABI = ap->Abi;
  7738.   }
  7739.  
  7740.   if(LastBias+BIAS_OFFSET < ap->Bias)
  7741.   {
  7742.     DoOutput("==reserve %ld\n", ((ap->Bias-LastBias)/BIAS_OFFSET)-1);
  7743.     LastBias = ap->Bias;
  7744.   }
  7745.   else if(flags & FUNCFLAG_TAG)
  7746.     DoOutput("==varargs\n");
  7747.   else if((flags & FUNCFLAG_ALIAS) || LastBias == ap->Bias)
  7748.     DoOutput("==alias\n");
  7749.   else
  7750.     LastBias += BIAS_OFFSET;
  7751.   
  7752.   if(!FuncClib(ap, flags, name))
  7753.     return 0;
  7754.  
  7755.   DoOutput(" ("/*)*/);
  7756.   if(!(ap->Flags & AMIPRAGFLAG_PPC))
  7757.   {
  7758.     strptr s;
  7759.  
  7760.     /* j runs in steps of two. If CPP_TYPE_DOUBLE is stored in data registers, it runs
  7761.        in step one, so the "-" can be placed at proper position. */
  7762.     for(j = i = 0; i < ap->NumArgs; i++)
  7763.     {
  7764.       if(i == ap->NumArgs-1)
  7765.       {
  7766.         s = ""; j += 2;
  7767.       }
  7768.       else if(IsCPPType(&cd->Args[j>>1], CPP_TYPE_DOUBLE) && ap->Args[i].ArgReg < REG_FP0)
  7769.       {
  7770.         s = (j&1) ? "," : "-"; ++j;
  7771.       }
  7772.       else
  7773.       {
  7774.         s = ","; j += 2;
  7775.       }
  7776.       DoOutput("%s%s", RegNames[ap->Args[i].ArgReg], s);
  7777.     }
  7778.   }
  7779.   return DoOutput(/*(*/")\n");
  7780. }
  7781.  
  7782. uint32 FuncGateStubs(struct AmiPragma *ap, uint32 flags, strptr name)
  7783. {
  7784.   struct ClibData *cd;
  7785.   strptr ret = "return ";
  7786.   int32 i;
  7787.  
  7788.   if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
  7789.     return 1;
  7790.  
  7791.   if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
  7792.     return 1;
  7793.  
  7794.   Flags |= FLAG_DONE; /* We did something */
  7795.  
  7796.   if(flags & FUNCFLAG_ALIAS)
  7797.   {
  7798.     if(flags & FUNCFLAG_TAG)
  7799.       return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
  7800.       Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name, ap->TagName);
  7801.  
  7802.     DoOutput("#define %s("/*)*/, name);
  7803.     for(i = 0; i < ap->NumArgs-1; ++i)
  7804.       DoOutput("%s, ", ap->Args[i].ArgName);
  7805.     DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
  7806.     for(i = 0; i < ap->NumArgs-1; ++i)
  7807.       DoOutput("(%s), ", ap->Args[i].ArgName);
  7808.     return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
  7809.   }
  7810.  
  7811.   if((flags & FUNCFLAG_TAG))
  7812.   {
  7813.     DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/, 
  7814.     Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name);
  7815.     for(i = 0; i < ap->NumArgs-1; ++i)
  7816.     {
  7817.       DoOutput("%s, ", ap->Args[i].ArgName);
  7818.     }
  7819.     DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
  7820.     ap->FuncName);
  7821.     for(i = 0; i < ap->NumArgs-1; ++i)
  7822.       DoOutput("(%s), ", ap->Args[i].ArgName);
  7823.     DoOutput("("/*)*/);
  7824.     OutClibType(&cd->Args[i], 0);
  7825.     return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
  7826.   }
  7827.  
  7828.   if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
  7829.     ret = "";
  7830.  
  7831.   if(!OutClibType(&cd->ReturnType, 0))
  7832.     return 0;
  7833.  
  7834.   DoOutput(" %s%s(void)\n{\n"/*}*/, prefix, name);
  7835.  
  7836.   for(i = 0; i < ap->NumArgs; ++i)
  7837.   {
  7838.     DoOutput("  ");
  7839.     OutClibType(&cd->Args[i], ap->Args[i].ArgName);
  7840.     DoOutput(" = ("/*)*/);
  7841.     OutClibType(&cd->Args[i], 0);
  7842.     DoOutput(/*(*/") REG_%s;\n", RegNamesUpper[ap->Args[i].ArgReg]);
  7843.     if((Flags2 & (FLAG2_PRELIB|FLAG2_POSTLIB)) && (Flags2 & FLAG2_REGLIB))
  7844.       DoOutput("  %s ___RegBase = (%s) REG_A6;\n", GetBaseType(), GetBaseType());
  7845.   }
  7846.   DoOutput("  %s%s%s("/*)*/, ret, subprefix, name);
  7847.   if(ap->NumArgs)
  7848.   {
  7849.     if(Flags2 & FLAG2_PRELIB)
  7850.     {
  7851.       if(Flags2 & FLAG2_REGLIB)
  7852.         DoOutput("___RegBase,");
  7853.       else
  7854.         DoOutput("%s_BASE_NAME,", ShortBaseNameUpper);
  7855.     }
  7856.  
  7857.     for(i = 0; i < ap->NumArgs-1; ++i)
  7858.     {
  7859.       DoOutput("%s, ", ap->Args[i].ArgName);
  7860.     }
  7861.     if(Flags2 & FLAG2_POSTLIB)
  7862.     {
  7863.       if(Flags2 & FLAG2_REGLIB)
  7864.         DoOutput("%s, ___RegBase", ap->Args[i].ArgName);
  7865.       else
  7866.         DoOutput("%s, %s_BASE_NAME", ap->Args[i].ArgName, ShortBaseNameUpper);
  7867.     }
  7868.     else
  7869.       DoOutput("%s", ap->Args[i].ArgName);
  7870.   }
  7871.   else
  7872.   {
  7873.     if(Flags2 & (FLAG2_PRELIB|FLAG2_POSTLIB))
  7874.     {
  7875.       if(Flags2 & FLAG2_REGLIB)
  7876.         DoOutput("___RegBase");
  7877.       else
  7878.         DoOutput("%s_BASE_NAME", ShortBaseNameUpper);
  7879.     }
  7880.   }
  7881.   return DoOutput(/*(({*/"));\n}\n");
  7882. }
  7883.  
  7884. static uint32 DoCallFunc(struct AmiPragma *ap, uint32 flags, strptr name, FuncType Func)
  7885. {
  7886.   uint32 res;
  7887.  
  7888.   if(Flags & FLAG_SINGLEFILE)
  7889.   {
  7890.     sprintf(filename, filenamefmt, name);
  7891.     if(!OpenDest(filename))
  7892.       return 0;
  7893.   }
  7894.   res = Func(ap, flags, name);
  7895.   if(Flags & FLAG_SINGLEFILE)
  7896.   {
  7897.     CloseDest(filename);
  7898.   }
  7899.   return res;
  7900. }
  7901.  
  7902. static uint32 PrintComment(struct Comment *com, strptr comment)
  7903. {
  7904.   if(com->Private && !(Flags & FLAG_PRIVATE))
  7905.     return 1;
  7906.   else if((Flags2 & FLAG2_SFDOUT) && com->Version)
  7907.   {
  7908.     return DoOutput("==version %d\n", com->Version);
  7909.   }
  7910.   else if((Flags2 & FLAG2_SFDOUT) && com->ReservedNum)
  7911.   {
  7912.     LastBias += BIAS_OFFSET*com->ReservedNum;
  7913.     return DoOutput("==reserve %d\n", com->ReservedNum);
  7914.   }
  7915.   else if(!(Flags & FLAG_DOCOMMENT) || !comment)
  7916.     return 1;
  7917.  
  7918.   if(com->Data)
  7919.   {
  7920.     if(!DoOutput(comment, com->Data))
  7921.       return 0;
  7922.   }
  7923.   else if(com->ReservedNum)
  7924.   {
  7925.     string temp[256];
  7926.     sprintf(temp, "* --- (%u function slot%s reserved here) ---", com->ReservedNum,
  7927.     com->ReservedNum == 1 ? "" : "s");
  7928.     if(!DoOutput(comment, temp))
  7929.       return 0;
  7930.   }
  7931.   else if(com->Version)
  7932.   {
  7933.     string temp[256];
  7934.     if(com->Version >= FIRST_KNOWN_RELEASE && com->Version <= LAST_KNOWN_RELEASE &&
  7935.     (Flags2 & FLAG2_SYSTEMRELEASE))
  7936.       sprintf(temp, "* --- functions in V%u or higher %s ---", com->Version,
  7937.       Release[com->Version-FIRST_KNOWN_RELEASE]);
  7938.     else
  7939.       sprintf(temp, "* --- functions in V%u or higher ---", com->Version);
  7940.  
  7941.     if(!DoOutput(comment, temp))
  7942.       return 0;
  7943.   }
  7944.   return 1;
  7945. }
  7946.  
  7947. static uint32 CallFunc(uint32 tagmode, strptr comment, FuncType Func)
  7948. {
  7949.   struct Comment *com;
  7950.   uint32 i;
  7951.   struct AmiPragma *ap;
  7952.  
  7953.   com = (struct Comment *) Comment.First;
  7954.  
  7955.   for(ap = (struct AmiPragma *) AmiPragma.First; ap;
  7956.   ap = (struct AmiPragma *) ap->List.Next)
  7957.   {
  7958.     if(BaseName && (ap->Flags & AMIPRAGFLAG_A6USE))
  7959.     {
  7960.       DoError(ERR_A6_NOT_ALLOWED, ap->Line);
  7961.     }
  7962.     else if((ap->Flags & AMIPRAGFLAG_PUBLIC) || (Flags & FLAG_PRIVATE))
  7963.     {
  7964.       while(com && com->Bias <= ap->Bias)
  7965.       {
  7966.         if(!PrintComment(com, comment))
  7967.           return 0;
  7968.         com = (struct Comment *) com->List.Next;
  7969.       } /* comment loop */
  7970.  
  7971. #ifdef DEBUG_OLD
  7972.   printf("Processing %s\n", ap->FuncName);
  7973. #endif
  7974.  
  7975.       if(tagmode != TAGMODE_TAGS)
  7976.       {
  7977.         if(ap->FuncName && !DoCallFunc(ap, FUNCFLAG_NORMAL, ap->FuncName, Func))
  7978.           return 0;
  7979.  
  7980.         for(i = 0; i < ap->NumAlias; ++i)
  7981.         {
  7982.           if(ap->AliasName[i]->Type & FUNCFLAG_NORMAL)
  7983.           {
  7984.             if(!DoCallFunc(ap, FUNCFLAG_ALIAS|ap->AliasName[i]->Type, ap->AliasName[i]->AliasName, Func))
  7985.               return 0;
  7986.           }
  7987.         }
  7988.       } 
  7989.  
  7990.       if(tagmode)
  7991.       {
  7992.         if(ap->TagName && !DoCallFunc(ap, FUNCFLAG_TAG, ap->TagName, Func))
  7993.           return 0;
  7994.  
  7995.         for(i = 0; i < ap->NumAlias; ++i)
  7996.         {
  7997.           if(ap->AliasName[i]->Type & FUNCFLAG_TAG)
  7998.           {
  7999.             if(!DoCallFunc(ap, FUNCFLAG_ALIAS|ap->AliasName[i]->Type, ap->AliasName[i]->AliasName, Func))
  8000.               return 0;
  8001.           }
  8002.         }
  8003.       }
  8004.     }
  8005.   }
  8006.   while(com)
  8007.   {
  8008.     if(!PrintComment(com, comment))
  8009.       return 0;
  8010.     com = (struct Comment *) com->List.Next;
  8011.   } /* comment loop */
  8012.   return 1;
  8013. }
  8014.  
  8015. static uint32 PrintIncludes(void) /* copies the include lines */
  8016. {
  8017.   struct Include *inc;
  8018.   strptr s, s2;
  8019.  
  8020.   inc = (struct Include *) Includes.First;
  8021.   
  8022.   while(inc)
  8023.   {
  8024.     s2 = (strptr) tempbuf;
  8025.     for(s = inc->Include; *s; ++s)
  8026.     {
  8027.       switch(*s)
  8028.       {
  8029.       case '<': *(s2++) = ' '; break;
  8030.       case '/':
  8031.       case '.': *(s2++) = '_'; break;
  8032.       case '>': break;
  8033.       default: *(s2++) = toupper(*s);
  8034.       }
  8035.       *s2 = 0;
  8036.     }
  8037.     DoOutput("#ifndef %s\n#include %s\n#endif\n", tempbuf, inc->Include);
  8038.     inc = (struct Include *) inc->List.Next;
  8039.   }
  8040.   if(!Includes.First)
  8041.     DoOutput("#include <exec/types.h>\n");
  8042.   return DoOutput("\n");
  8043. }
  8044.  
  8045. /* ------------------------------------------------------------------ */
  8046.  
  8047. static int32 AddClibEntry(strptr buffer, strptr bufend, uint32 linenum)
  8048. {
  8049.   strptr buf = buffer;
  8050.   struct ClibData d, *f;
  8051.  
  8052.   memset(&d, 0, sizeof(struct ClibData));
  8053.   buf = SkipBlanks(buf);
  8054.   if(*buf == '#') /* preprozessor lines */
  8055.   {
  8056. #ifdef DEBUG_OLD
  8057.   printf("Found non-function bracket in preprozessor line %ld\n", linenum);
  8058. #endif
  8059.     while(buf < bufend && *buf != '\n')
  8060.       ++buf;
  8061.     return buf-buffer;
  8062.   }
  8063.   if(!strnicmp(buf, "ASM", 3))
  8064.     buf = SkipBlanks(buf+3);
  8065. /*  else if(!strnicmp(buf, "STACK", 5))
  8066.     buf = SkipBlanks(buf+5);
  8067. */
  8068.   else if(!strnicmp(buf, "REGS", 4))
  8069.     buf = SkipBlanks(buf+4);
  8070.  
  8071.   if(!strnicmp(buf, "extern", 6))
  8072.     buf = SkipBlanks(buf+6);
  8073.  
  8074.   if(!GetCPPType(&d.ReturnType, buf, 1, 1))
  8075.   {
  8076.     DoError(ERROFFSET_CLIB | ERR_UNKNOWN_RETURNVALUE_TYPE, linenum);
  8077.     return 0;
  8078.   }
  8079.   else if(d.ReturnType.Unknown)
  8080.     DoError(ERROFFSET_CLIB | ERR_UNKNOWN_RETURNVALUE_TYPE_INT, linenum,
  8081.     d.ReturnType.Unknown);
  8082.  
  8083.   if(d.ReturnType.Flags & CPP_FLAG_FUNCTION)
  8084.   {
  8085.     strptr r = d.ReturnType.TypeStart;
  8086.     while(*r != '('/*)*/) ++r;
  8087.     r = SkipBlanks(++r); /* the bracket */
  8088.     d.FuncName = SkipBlanks(++r); /* the asterix */
  8089.   }
  8090.   else
  8091.     d.FuncName = SkipBlanks(d.ReturnType.TypeStart+d.ReturnType.FullLength);
  8092.   buf = d.FuncName;
  8093.   while(*(buf++) != '('/*)*/)
  8094.     ;
  8095.   *(SkipName(d.FuncName)) = 0;
  8096.   if(!(*d.FuncName))
  8097.   {
  8098. #ifdef DEBUG_OLD
  8099.   printf("Found non-function bracket in line %ld\n", linenum);
  8100. #endif
  8101.     while(buf < bufend && *buf != '\n')
  8102.       ++buf;
  8103.     return buf-buffer;
  8104.   }
  8105.   buf = SkipBlanksRet(buf);
  8106.  
  8107.   while(*buf != /*(*/')' && buf < bufend)
  8108.   {
  8109.     if(d.NumArgs == MAXREGPPC+1)
  8110.     {
  8111.       DoError(ERROFFSET_CLIB | ERR_TO_MUCH_ARGUMENTS, linenum);
  8112.       return 0;
  8113.     }
  8114.     else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 0, 1))
  8115.     {
  8116.       DoError(ERROFFSET_CLIB | ERR_UNKNOWN_VARIABLE_TYPE, linenum, d.NumArgs);
  8117.       return 0;
  8118.     }
  8119.     else if(d.Args[d.NumArgs-1].Unknown)
  8120.       DoError(ERROFFSET_CLIB | ERR_UNKNOWN_VARIABLE_TYPE_INT, linenum,
  8121.       d.NumArgs, d.Args[d.NumArgs-1].Unknown);
  8122.  
  8123.     buf = d.Args[d.NumArgs-1].TypeStart + d.Args[d.NumArgs-1].FullLength;
  8124.     while(*buf != ',' && *buf != /*(*/')' && buf < bufend)
  8125.       ++buf;
  8126. #ifdef DEBUG
  8127.   printf("Added argument %ld for %s (%ld bytes)\n", d.NumArgs, d.FuncName,
  8128.   d.Args[d.NumArgs-1].FullLength);
  8129. #endif
  8130.     if(*buf == ',')
  8131.       buf = SkipBlanksRet(++buf);
  8132.   }
  8133.  
  8134.   if(d.NumArgs == 1 && IsCPPType(&d.Args[0], CPP_TYPE_VOID))
  8135.     d.NumArgs = 0; /* void arguments are no arguments */
  8136.  
  8137.   if(!(f = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
  8138.     return -1;
  8139.  
  8140.   memcpy(f, &d, sizeof(struct ClibData));
  8141.  
  8142.   if(!clibdata)
  8143.     clibdata = f;
  8144.   else
  8145.   {
  8146.     struct ClibData *e = clibdata;
  8147.     while(e->Next)
  8148.       e = e->Next;
  8149.     e->Next = f;
  8150.   }
  8151.   if(d.ReturnType.Flags & CPP_FLAG_FUNCTION)
  8152.   {
  8153.     int numclose = 2, numopen = 1;
  8154.     while(buf < bufend && (numclose || numopen > 0))
  8155.     {
  8156.       if(*buf == '('/*)*/) { ++numclose; --numopen; }
  8157.       else if(*buf == /*(*/')') --numclose;
  8158.       ++buf;
  8159.     }
  8160.   }
  8161.  
  8162. #ifdef DEBUG
  8163.   printf("Added prototype for %s (line %ld, %ld bytes) with %ld args\n",
  8164.   f->FuncName, linenum, buf-buffer, f->NumArgs);
  8165. #endif
  8166.   return buf-buffer;
  8167. }
  8168.  
  8169. static int32 ScanClibFile(strptr buf, strptr bufend)
  8170. {
  8171.   strptr linestart = buf;
  8172.   uint32 linenum = 1;
  8173.  
  8174.   /* remove comments and other not so nice characters */
  8175.   while(buf < bufend)
  8176.   {
  8177.     if(*buf == '\t' || *buf == '\r' || *buf == (string)0xA0)
  8178.       *(buf++) = ' ';
  8179.     else if(buf[0] == '/' && buf < bufend-1)
  8180.     {
  8181.       if(buf[1] == '*')
  8182.       {
  8183.         while(buf < bufend-1 && (buf[0] != '*' || buf[1] != '/'))
  8184.         {
  8185.           if(*buf != '\n')
  8186.             *buf = ' ';
  8187.           ++buf;
  8188.         }
  8189.         *(buf++) = ' ';
  8190.         *(buf++) = ' ';
  8191.       }
  8192.       else if(buf[1] == '/')
  8193.       {
  8194.         while(buf < bufend && buf[0] != '\n')
  8195.           *(buf++) = ' ';
  8196.         ++buf;
  8197.       }
  8198.       else
  8199.         ++buf;
  8200.     }
  8201.     else if(buf[0] == '#' && strncmp("#include", buf, 8))
  8202.     {
  8203.       while(buf < bufend && buf[0] != '\n')
  8204.         *(buf++) = ' ';
  8205.       ++buf;
  8206.     }
  8207.     else
  8208.       ++buf;
  8209.   }
  8210.  
  8211. #ifdef DEBUG_OLD
  8212.   printf("-----------\n%s-----------\n", linestart);
  8213. #endif
  8214.  
  8215.   buf = linestart;
  8216.   while(buf < bufend)
  8217.   {
  8218.     if(*buf == '\n')
  8219.     {
  8220.       linestart = ++buf; ++linenum;
  8221.     }
  8222.     else if(!strncmp("#include", buf, 8))
  8223.     {
  8224.       struct Include *d;
  8225.  
  8226.       if(!(d = (struct Include *) NewItem(&Includes)))
  8227.         return 0;
  8228.       d->Include = buf = SkipBlanks(buf+8);
  8229.       AddItem(&Includes, (struct ShortList *) d);
  8230.       while(*buf && *buf != '>' && *buf != '\n')
  8231.         ++buf;
  8232.       if(*buf == '>')
  8233.         ++buf;
  8234.       if(*buf == '\n')
  8235.         ++linenum;
  8236.       *(buf++) = 0;
  8237. #ifdef DEBUG_OLD
  8238.   printf("Added Include line %s\n", d->Include);
  8239. #endif
  8240.     }
  8241.     else if(*buf == '('/*)*/)
  8242.     {
  8243.       int32 i;
  8244.  
  8245.       if((i = AddClibEntry(linestart, bufend, linenum)) == -1) /* no memory */
  8246.         return 0;
  8247.       else if(!i)
  8248.       {
  8249.         while(buf < bufend && *buf != '\n')
  8250.           ++buf; /* skip this line */
  8251.       }
  8252.       else
  8253.       {
  8254.         i -= buf-linestart;
  8255.         while(buf < bufend && i-- > 0)
  8256.         {
  8257.           if(*(buf++) == '\n')
  8258.           {
  8259.             linestart = buf;
  8260.             ++linenum;
  8261.           } /* skip this function */
  8262.         }
  8263.       }
  8264.     }
  8265.     else
  8266.       ++buf;
  8267.   } /* while */
  8268.   return 1;
  8269. }
  8270.  
  8271. static int32 IsCPPType(struct CPP_NameType *data, uint8 type)
  8272. {
  8273.   if(!data || data->Flags || data->Type != type || data->PointerDepth)
  8274.     return 0;
  8275.   return type;
  8276. }
  8277.  
  8278. static uint32 CheckRegisterNum(strptr string, struct CPP_NameType *data)
  8279. {
  8280.   uint32 i, j;
  8281.   
  8282.   for(i = 0; i < MAXREG; ++i)
  8283.   {
  8284.     j = strlen(RegNames[i]);
  8285.     if(!strnicmp(string, RegNames[i], j))
  8286.     {
  8287.       string += j;
  8288.       if(*string == ' ' || *string == '\t' || *string == '\n' || *string == /*(*/')')
  8289.       {
  8290.         data->Register = i;
  8291.         data->Flags |= CPP_FLAG_REGISTER;
  8292.         return j;
  8293.       }
  8294.     }
  8295.   }
  8296.   return 0;
  8297. }
  8298.  
  8299. static uint32 ParseFuncPtrArgs(strptr buffer, struct CPP_NameType *data)
  8300. {
  8301.   strptr buf = buffer;
  8302.   struct ClibData d;
  8303.  
  8304.   memset(&d, 0, sizeof(struct ClibData));
  8305.   while(*buf != /*(*/')')
  8306.   {
  8307.     if(d.NumArgs == MAXREGPPC+1)
  8308.       return 0;
  8309.     else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 1, 1))
  8310.       return 0;
  8311.  
  8312.     buf += d.Args[d.NumArgs-1].FullLength;
  8313.     while(*buf != ',' && *buf != /*(*/')')
  8314.       ++buf;
  8315.     if(*buf == ',')
  8316.       buf = SkipBlanksRet(++buf);
  8317.   }
  8318.  
  8319.   if(d.NumArgs == 1 && IsCPPType(&d.Args[0], CPP_TYPE_VOID))
  8320.     d.NumArgs = 0; /* void arguments are no arguments */
  8321.  
  8322.   if(d.NumArgs) /* no need to allocate structure for nothing */
  8323.   {
  8324.     if(!(data->FuncPtr = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
  8325.       return 0;
  8326.  
  8327.     memcpy(data->FuncPtr, &d, sizeof(struct ClibData));
  8328.   }
  8329.   return (uint32) (buf+1-buffer);
  8330. }
  8331.  
  8332. /* rettype turns on usage of "extern" specifier */
  8333. static int32 GetCPPType(struct CPP_NameType *data, strptr start, uint32 rettype, uint32 small)
  8334. {
  8335.   uint32 ok = 1, j;
  8336.   strptr u;
  8337.  
  8338.   data->Unknown = 0;
  8339.   data->Replace = 0;
  8340.   data->TypeStart = start = SkipBlanks(start);
  8341.  
  8342.   if(!strncmp(start, "REG", 3) && (start[3] == ' ' || start[3] == '\t' || start[3] == '\n' || start[3] == '('/*)*/))
  8343.   {
  8344.     u = SkipBlanksRet(start+3);
  8345.     if(*u == '('/*)*/)
  8346.     {
  8347.       u = SkipBlanks(u+1);
  8348.       if((j = CheckRegisterNum(u, data)))
  8349.       {
  8350.         u = SkipBlanks(u+j);
  8351.         if(*u == ')')
  8352.           start = SkipBlanks(u+1);
  8353.       }
  8354.     }
  8355.   }
  8356.   data->TypeStart = start;
  8357.  
  8358.   do
  8359.   {
  8360.     start = SkipBlanks((u = start));
  8361.     if(!strncmp("...",start,3))
  8362.     {
  8363.       data->Type = CPP_TYPE_VARARGS;
  8364.       data->TypeLength = start+3 - (data->TypeStart);
  8365.       data->FullLength = data->TypeLength;
  8366.       return 1;
  8367.     }
  8368.     if(CheckKeyword(start, "const", 5) || CheckKeyword(start, "CONST", 5))
  8369.     {
  8370.       data->Flags |= CPP_FLAG_CONST; start += 6;
  8371.     }
  8372.     else if(rettype && CheckKeyword(start, "extern", 6))
  8373.     {
  8374.       start += 7; /* ignore it */
  8375.     }
  8376.     else if(CheckKeyword(start, "signed", 6))
  8377.       start += 7;
  8378.     else if(CheckKeyword(start, "unsigned", 8))
  8379.     {
  8380.       data->Flags |= CPP_FLAG_UNSIGNED; start += 9;
  8381.     }
  8382.     else if(CheckKeyword(start, "register", 8))
  8383.     {
  8384.       data->Flags |= CPP_FLAG_REGISTER; start += 9;
  8385.       data->Register = UNDEFREGISTER;
  8386.     }
  8387.     else if(CheckKeyword(start, "struct", 6))
  8388.     {
  8389.       start = SkipBlanks(start+6);
  8390.       data->Flags |= CPP_FLAG_STRUCT;
  8391.       if(*start == '?') /* ? for external types */
  8392.       {
  8393.         data->StructureLength = 0;
  8394.         data->StructureName = "";
  8395.         ++start;
  8396.       }
  8397.       else if(*start == '!') /* ! for typedef types */
  8398.       {
  8399.         data->Flags |= CPP_FLAG_TYPEDEFNAME;
  8400.         ++start;
  8401.         /* structure name and length already set */
  8402.       }
  8403.       else
  8404.       {
  8405.         start = SkipName((data->StructureName = start));
  8406.         data->StructureLength = start-data->StructureName;
  8407.       }
  8408.     }
  8409.     else if(CheckKeyword(start, "union", 5))
  8410.     {
  8411.       start = SkipBlanks(start+5);
  8412.       data->Flags |= CPP_FLAG_UNION;
  8413.       if(*start != '?') /* ? for external types */
  8414.       {
  8415.         start = SkipName((data->StructureName = start));
  8416.         data->StructureLength = start-data->StructureName;
  8417.       }
  8418.       else
  8419.       {
  8420.         data->StructureLength = 0;
  8421.         data->StructureName = "";
  8422.         ++start;
  8423.       }
  8424.     }
  8425.     else if(CheckKeyword(start, "enum", 4))
  8426.     {
  8427.       start = SkipBlanks(start+4);
  8428.       data->Flags |= CPP_FLAG_ENUM;
  8429.       if(*start != '?') /* ? for external types */
  8430.       {
  8431.         start = SkipName((data->StructureName = start));
  8432.         data->StructureLength = start-data->StructureName;
  8433.       }
  8434.       else
  8435.       {
  8436.         data->StructureLength = 0;
  8437.         data->StructureName = "";
  8438.         ++start;
  8439.       }
  8440.     }
  8441.     else if(*start == '*')
  8442.     {
  8443.       ++start; ++data->PointerDepth;
  8444.     }
  8445.     else if(*start == '[')
  8446.     {
  8447.       data->Flags |= CPP_FLAG_ARRAY;
  8448.       while(*start && *start != ']')
  8449.         ++start;
  8450.       if(*start)
  8451.         ++start;
  8452.     }
  8453.     else if(start[0] == '_' && start[1] == '_' && (j = CheckRegisterNum(start+2, data)))
  8454.       start += 2 + j;
  8455.     else if(!data->Type)
  8456.     {
  8457.       uint32 i;
  8458.  
  8459.       for(i = 0; CPP_Field[i].Text; ++i)
  8460.       {
  8461.         if(!strncmp(start, CPP_Field[i].Text, CPP_Field[i].Length) &&
  8462.         (start[CPP_Field[i].Length] == ' ' ||
  8463.         start[CPP_Field[i].Length] == '\t' ||
  8464.         start[CPP_Field[i].Length] == '\n' ||
  8465.         start[CPP_Field[i].Length] == ',' ||
  8466.         start[CPP_Field[i].Length] == /*(*/')' ||
  8467.         start[CPP_Field[i].Length] == '('/*)*/ ||
  8468.         start[CPP_Field[i].Length] == '*'))
  8469.         {
  8470.           start += CPP_Field[i].Length;
  8471.           data->Type = CPP_Field[i].Type;
  8472.           data->Flags |= CPP_Field[i].Flags;
  8473.           if(CPP_Field[i].Flags & CPP_FLAG_POINTER)
  8474.             ++data->PointerDepth;
  8475.           break;
  8476.         }
  8477.       }
  8478.       if(CPP_Field[i].Text)
  8479.         continue;
  8480.       else if(extnames)
  8481.       {
  8482.         struct CPP_ExternNames *a = extnames;
  8483.        
  8484.         while(a)
  8485.         {
  8486.           i = strlen(a->Type);
  8487.           if(!strncmp(a->Type, start, i) && !isalnum(start[i]) && 
  8488.           start[i] != '_')
  8489.           {
  8490.             start += i;
  8491.             data->StructureName = a->NameType.StructureName;
  8492.             data->FuncPtr = a->NameType.FuncPtr;
  8493.             data->StructureLength = a->NameType.StructureLength;
  8494.             data->PointerDepth += a->NameType.PointerDepth;
  8495.             data->Type = a->NameType.Type;
  8496.             data->Flags |= a->NameType.Flags;
  8497.             data->FuncArgs = a->NameType.FuncArgs;
  8498.             data->ArgsLength = a->NameType.ArgsLength;
  8499.             break;
  8500.           }
  8501.      
  8502.           /* check types here */
  8503.           a = a->Next;
  8504.         }
  8505.         if(a)
  8506.           continue;
  8507.         else if((!data->Type) && (!data->Flags))
  8508.         {
  8509.           long size;
  8510.           struct CPP_Unknown *u;
  8511.  
  8512.           data->Type = CPP_TYPE_INT;
  8513.           size = SkipName(start)-start;
  8514.           for(u = unknown; u && strncmp(u->Unknown, start, size); u = u->Next)
  8515.             ;
  8516.           if(!u)
  8517.           {
  8518.             data->Unknown = DupString(start, size);
  8519.             if((u = (struct CPP_Unknown *) AllocListMem(sizeof(struct CPP_Unknown))))
  8520.             {
  8521.               u->Next = unknown;
  8522.               u->Unknown = data->Unknown;
  8523.               unknown = u;
  8524.             }
  8525.           }
  8526.           start += size;
  8527.           continue;
  8528.         }
  8529.       }
  8530.       break;
  8531.     }
  8532.     else
  8533.       break;
  8534.   }while(1);
  8535.  
  8536.   if(start != SkipBlanks(u)) /* we broke the loop after increasing start */
  8537.     u = start;
  8538.  
  8539.   data->TypeLength = u - (data->TypeStart);
  8540.   data->FullLength = data->TypeLength;
  8541.  
  8542.   u = SkipBlanks(u);
  8543.  
  8544.   if(*u == '('/*)*/)
  8545.   {
  8546.     ok = 0;
  8547.     u = SkipBlanks(++u);
  8548.     if(*u == '*')
  8549.     {
  8550.       while(*u == '*')
  8551.       {
  8552.         ++data->FuncPointerDepth; ++u;
  8553.       }
  8554.       u = SkipBlanks(u);
  8555.       if(CheckKeyword(u, "const", 5) || CheckKeyword(u, "CONST", 5))
  8556.       {
  8557.         data->Flags |= CPP_FLAG_CONST; u += 6;
  8558.       }
  8559.       u = SkipBlanks(u);
  8560.       if(*u != /*(*/')')
  8561.         data->FunctionName = u;
  8562.       u = SkipBlanks(SkipName(u));
  8563.       if(*u == '('/*)*/)
  8564.       {
  8565.         int numclose = 1;
  8566.         ++u;
  8567.         while(*u && numclose)
  8568.         {
  8569.           if(*u == '('/*)*/) ++numclose;
  8570.           else if(*u == /*(*/')') --numclose;
  8571.           ++u;
  8572.         }
  8573.       }
  8574.       if(*u == /*(*/')')
  8575.       {
  8576.         u = SkipBlanks(++u);
  8577.         if(*u == '('/*)*/)
  8578.         {
  8579.           data->Flags |= CPP_FLAG_FUNCTION;
  8580.  
  8581.           if((j = ParseFuncPtrArgs(u+1, data)))
  8582.             ok = 1;
  8583.           data->FuncArgs = u;
  8584.           data->ArgsLength = j+1;
  8585.           data->FullLength = u+data->ArgsLength - (data->TypeStart);
  8586.         }
  8587.       }
  8588.     }
  8589.   }
  8590.  
  8591.   if(data->PointerDepth)
  8592.     data->Flags |= CPP_FLAG_POINTER;
  8593.  
  8594.   if(!(Flags2 & FLAG2_SMALLTYPES) && !small)
  8595.   {
  8596.     if(!(data->Flags & (CPP_FLAG_STRPTR|CPP_FLAG_POINTER|CPP_FLAG_ENUM
  8597.     |CPP_FLAG_STRUCT|CPP_FLAG_UNION|CPP_FLAG_FUNCTION|CPP_FLAG_REGISTER)))
  8598.     {
  8599.       if(data->Type == CPP_TYPE_BYTE || data->Type == CPP_TYPE_WORD || data->Type == CPP_TYPE_INT)
  8600.       {
  8601.         if(data->Flags & CPP_FLAG_UNSIGNED)
  8602.           data->Replace = "const ULONG";
  8603.         else
  8604.           data->Replace = "const LONG";
  8605.         data->Type = CPP_TYPE_LONG;
  8606.         if(!(data->Flags & CPP_FLAG_CONST))
  8607.           data->Replace += 6;
  8608.       }
  8609.     }
  8610.   }
  8611.  
  8612.   if((!data->Type && !data->Flags) || !ok)
  8613.     return 0;
  8614.   return 1;
  8615. }
  8616.  
  8617. static struct ClibData *GetClibFunc(strptr name, struct AmiPragma *ap, uint32 flags)
  8618. {
  8619.   struct ClibData *d = clibdata;
  8620.  
  8621.   while(d && strcmp(name, d->FuncName))
  8622.     d = d->Next;
  8623.  
  8624.   if(!d)
  8625.   {
  8626.     if(!(ap->Flags & AMIPRAGFLAG_NOCLIB))
  8627.     {
  8628.       DoError(ERR_PROTOTYPE_MISSING, 0, name);
  8629.       ap->Flags |= AMIPRAGFLAG_NOCLIB;
  8630.     }
  8631.   }
  8632.   else if(ap->CallArgs != d->NumArgs && (!(flags & FUNCFLAG_TAG) ||
  8633.   ap->CallArgs+1 != d->NumArgs))
  8634.   {
  8635.     if(!(ap->Flags & (AMIPRAGFLAG_CLIBARGCNT|AMIPRAGFLAG_DIDARGWARN)))
  8636.     {
  8637.       DoError(ERR_CLIB_ARG_COUNT, 0, name, d->NumArgs, ap->NumArgs);
  8638.       ap->Flags |= AMIPRAGFLAG_CLIBARGCNT;
  8639.     }
  8640.     return 0;
  8641.   }
  8642.  
  8643.   return d;  
  8644. }
  8645.  
  8646. static int32 CheckKeyword(strptr string, strptr keyword, int32 size)
  8647. {
  8648.   if(!strncmp(string, keyword, size))
  8649.   {
  8650.     string += size;
  8651.     if(*string == ' ' || *string == '\t' || *string == '\n')
  8652.       return size;
  8653.   }
  8654.   return 0;
  8655. }
  8656.  
  8657. /* return nonzero, when usable, zero, when string already emitted */
  8658. static uint32 CopyCPPType(strptr buffer, uint32 pass, struct ClibData *cd,
  8659. struct AmiArgs *args)
  8660. {
  8661.   uint32 ret = 0, reg;
  8662.   uint32 i, j, k = 0;
  8663.  
  8664. /* pass 0:   signed strptr, MaxonC++ high args */
  8665. /* pass 1: unsigned strptr, MaxonC++ high args */
  8666. /* pass 2:   signed strptr, StormC++ high args */
  8667. /* pass 3: unsigned strptr, StormC++ high args */
  8668.  
  8669.   for(i = 0; i < cd->NumArgs; ++i)
  8670.   {
  8671.     struct CPP_NameType *nt;
  8672.  
  8673.     nt = &cd->Args[i];
  8674.  
  8675.     if(args && (Flags & FLAG_LOCALREG) && (nt->Type != CPP_TYPE_VARARGS))
  8676.       reg = 1 + args[k].ArgReg;
  8677.     else if((nt->Flags & CPP_FLAG_REGISTER) && nt->Register != UNDEFREGISTER)
  8678.       reg = 1 + nt->Register;
  8679.     else
  8680.       reg = 0;
  8681.  
  8682.     if(reg--) /* subtract the added 1 */
  8683.     {
  8684.       *(buffer++) = CPP_TYPE_REGISTER;
  8685.       if(reg >= 10)
  8686.       {
  8687.         if(pass & 2)
  8688.         {
  8689.           *(buffer++) = reg/10 + '0';
  8690.           *(buffer++) = reg%10 + '0';
  8691.           ret |= 2;
  8692.         }
  8693.         else
  8694.           *(buffer++) = reg + (reg < 10 ? '0' : 'A'-10);
  8695.       }
  8696.       else
  8697.         *(buffer++) = reg + '0';
  8698.     }
  8699.  
  8700.     if(nt->Flags & CPP_FLAG_FUNCTION)
  8701.     {
  8702.       for(j = 0; j < nt->FuncPointerDepth; ++j)
  8703.         *(buffer++) = CPP_TYPE_POINTER;
  8704.       *(buffer++) = CPP_TYPE_FUNCTION;
  8705.     }
  8706.     for(j = 0; j < nt->PointerDepth; ++j)
  8707.       *(buffer++) = CPP_TYPE_POINTER;
  8708.     if(nt->Flags & CPP_FLAG_CONST)
  8709.       *(buffer++) = CPP_TYPE_CONST;
  8710.     if(nt->Flags & CPP_FLAG_UNSIGNED)
  8711.       *(buffer++) = CPP_TYPE_UNSIGNED;
  8712.     else if((nt->Flags & CPP_FLAG_STRPTR) && (pass & 1))
  8713.     {
  8714.       *(buffer++) = CPP_TYPE_UNSIGNED;
  8715.       ret |= 1; /* we really use this pass */
  8716.     }
  8717.     if(nt->Flags & CPP_FLAG_ENUM)
  8718.       *(buffer++) = CPP_TYPE_ENUM;
  8719.     if(nt->Type)
  8720.       *(buffer++) = cd->Args[i].Type;
  8721.     else
  8722.     {
  8723.       uint32 i;
  8724.       sprintf(buffer, "%02lu", (uint32) nt->StructureLength); buffer += 2;
  8725.       for(i = 0; i < nt->StructureLength; ++i)
  8726.         *(buffer++) = nt->StructureName[i];
  8727.     }
  8728.     if(nt->Flags & CPP_FLAG_FUNCTION)
  8729.     {
  8730.       if(nt->FuncPtr)
  8731.       {
  8732.         ret |= CopyCPPType(buffer, pass, nt->FuncPtr, 0);
  8733.         while(*buffer)
  8734.           ++buffer; /* skip to the new end */
  8735.       }
  8736.       *(buffer++) = CPP_TYPE_FUNCEND;
  8737.     }
  8738.     ++k;
  8739.     if(IsCPPType(nt, CPP_TYPE_DOUBLE))  /* double needs 2 registers */
  8740.       ++k;
  8741.   }
  8742.  
  8743.   *(buffer) = 0;
  8744.  
  8745.   if(ret != pass)
  8746.     ret = 0;
  8747.   if(!pass)
  8748.     ret = 0x80;
  8749.  
  8750.   return ret;  /* return nozero if this pass should be used */
  8751. }
  8752.  
  8753. static uint32 OutClibType(struct CPP_NameType *nt, strptr txt)
  8754. {
  8755.   if(nt->Replace)
  8756.     DoOutput("%s", nt->Replace);
  8757.   else
  8758.     DoOutputDirect(nt->TypeStart, nt->TypeLength);
  8759.   if(nt->Type != CPP_TYPE_VARARGS)
  8760.   {
  8761.     if(nt->Flags & CPP_FLAG_FUNCTION)
  8762.     {
  8763.       uint32 i;
  8764.       DoOutput(" ("/*)*/);
  8765.       for(i = 0; i < nt->FuncPointerDepth; ++i)
  8766.         DoOutput("*");
  8767.       DoOutput(/*((*/txt ? "%s)" : ")", txt);
  8768.       if(nt->FuncArgs)
  8769.         return DoOutputDirect(nt->FuncArgs, nt->ArgsLength);
  8770.       else
  8771.         return DoOutput("()");
  8772.     }
  8773.     else if(txt)
  8774.       return DoOutput(" %s", txt);
  8775.   }
  8776.  
  8777.   return 1;
  8778. }
  8779.  
  8780. static uint32 MakeClibType(strptr dest, struct CPP_NameType *nt, strptr txt)
  8781. {
  8782.   strptr a;
  8783.  
  8784.   a = dest;
  8785.   if(nt->Replace)
  8786.   {
  8787.     uint32 i;
  8788.     i = strlen(nt->Replace);
  8789.     memcpy(a, nt->Replace, i);
  8790.     a += i;
  8791.   }
  8792.   else
  8793.   {
  8794.     memcpy(a, nt->TypeStart, nt->TypeLength);
  8795.     a += nt->TypeLength;
  8796.   }
  8797.  
  8798.   if(nt->Type != CPP_TYPE_VARARGS)
  8799.   {
  8800.     if(nt->Flags & CPP_FLAG_FUNCTION)
  8801.     {
  8802.       a += sprintf(a, (txt ? " (*%s)" : " (*)"), txt);
  8803.       if(nt->FuncArgs)
  8804.       {
  8805.         memcpy(a, nt->FuncArgs, nt->ArgsLength);
  8806.         a += nt->ArgsLength;
  8807.       }
  8808.       else
  8809.         a += sprintf(a, "()");
  8810.     }
  8811.     else if(txt)
  8812.       a += sprintf(a, " %s", txt);
  8813.   }
  8814.   return (uint32)(a-dest);
  8815. }
  8816.  
  8817. static uint32 OutPASCALType(struct CPP_NameType *t, strptr txt, uint32 ret)
  8818. {
  8819.   int32 i = t->PointerDepth;
  8820.  
  8821.   if(t->Flags & CPP_FLAG_CONST)
  8822.     DoOutput("CONST ");
  8823.   if(!ret && i == 1 &&
  8824.   (t->Type == CPP_TYPE_LONG || t->Type == CPP_TYPE_WORD))
  8825.   {
  8826.     DoOutput("VAR "); --i;
  8827.   }
  8828.  
  8829.   DoOutput("%s : ", txt);
  8830.  
  8831.   if(!i && t->Flags == CPP_FLAG_BOOLEAN)
  8832.     return DoOutput("BOOLEAN");
  8833.   else if(i && t->Type == CPP_TYPE_VOID)
  8834.     return DoOutput("POINTER");
  8835.   else if(t->Flags & CPP_FLAG_FUNCTION)
  8836.     return DoOutput("tPROCEDURE");
  8837.  
  8838.   while(i--)
  8839.     DoOutput("p");
  8840.  
  8841.   if((t->Flags & (CPP_FLAG_STRUCT|CPP_FLAG_UNION)) && t->StructureLength)
  8842.   {
  8843.     if(!t->PointerDepth)
  8844.       DoOutput("t");
  8845.     return DoOutputDirect(t->StructureName, t->StructureLength);
  8846.   }
  8847.  
  8848.   if(t->Flags & CPP_FLAG_UNSIGNED)
  8849.   {
  8850.     if(t->Type == CPP_TYPE_LONG)
  8851.       return DoOutput("CARDINAL");
  8852.     if(t->Type == CPP_TYPE_WORD)
  8853.       return DoOutput("int16");
  8854.     if(t->Type == CPP_TYPE_BYTE)
  8855.       return DoOutput(t->PointerDepth == 1 ? "CHAR" : "int8");
  8856.   }
  8857.   else if(t->Type == CPP_TYPE_WORD)
  8858.     return DoOutput("INTEGER");
  8859.   else if(t->Type == CPP_TYPE_BYTE)
  8860.     return DoOutput("SHORTINT");
  8861.   return DoOutput("int32INT");
  8862. }
  8863.  
  8864. /* ------------------------------------------------------------------ */
  8865.  
  8866. static uint32 CallPrag(uint32 tagmode, strptr type, FuncType Func)
  8867. {
  8868.   if(type)
  8869.     if((*type && !DoOutput("#if%s\n", type)) ||
  8870.     !(CallFunc(tagmode, tagmode ? 0 : "/%s */\n", Func)) ||
  8871.     (*type && !DoOutput("#endif\n")))
  8872.       return 0;
  8873.   return 1;
  8874. }
  8875.  
  8876. static uint32 CreatePragmaFile(strptr amicall, strptr libcall, strptr amitags,
  8877. strptr libtags, uint32 mode)
  8878. {
  8879.   if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  8880.  
  8881.   switch(mode)
  8882.   {
  8883.   case PRAGMODE_PRAGLIB: DoOutput("#ifndef _INCLUDE_PRAGMA_%s_LIB_H\n"
  8884.     "#define _INCLUDE_PRAGMA_%s_LIB_H\n", ShortBaseNameUpper,
  8885.     ShortBaseNameUpper); break;
  8886.   case PRAGMODE_PRAGSLIB: DoOutput("#ifndef PRAGMAS_%s_LIB_H\n#define "
  8887.     "PRAGMAS_%s_LIB_H\n", ShortBaseNameUpper, ShortBaseNameUpper); break;
  8888.   case PRAGMODE_PRAGSPRAGS: DoOutput("#ifndef PRAGMAS_%s_PRAGMAS_H\n#define "
  8889.     "PRAGMAS_%s_PRAGMAS_H\n", ShortBaseNameUpper, ShortBaseNameUpper); break;
  8890.   case PRAGMODE_NONE: break;
  8891.   default: return 0;
  8892.   }
  8893.  
  8894.   if(HEADER)
  8895.   {
  8896.     DoOutput("\n");
  8897.     DoOutputDirect(HEADER, headersize);
  8898.   }
  8899.  
  8900.   if(mode != PRAGMODE_NONE && !DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
  8901.   "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
  8902.     return 0;
  8903.  
  8904.   if((Flags & FLAG_EXTERNC) &&
  8905.   !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
  8906.     return 0;
  8907.  
  8908.   if(Flags & FLAG_GNUPRAG)
  8909.   {
  8910.     DoOutput("#ifdef " TEXT_GNUC "\n#ifdef NO_OBSOLETE\n"
  8911.     "#error \"Please include the proto file and not the compiler specific file!\"\n"
  8912.     "#endif\n#include <inline/%s.h>\n#endif\n\n", ShortBaseName);
  8913.     Flags |= FLAG_DONE;
  8914.   }
  8915.  
  8916.   if(
  8917.   !CallPrag(TAGMODE_NORMAL, amicall, FuncAMICALL) ||
  8918.   !CallPrag(TAGMODE_NORMAL, libcall, FuncLIBCALL))
  8919.     return 0;
  8920.  
  8921.   if(tagfuncs)
  8922.   {
  8923.     if(
  8924.     !CallPrag(TAGMODE_TAGS, amitags, FuncAMICALL) ||
  8925.     !CallPrag(TAGMODE_TAGS, libtags, FuncLIBCALL))
  8926.       return 0;
  8927.   }
  8928.  
  8929.   if((Flags & FLAG_EXTERNC) &&
  8930.   !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
  8931.     return 0;
  8932.  
  8933.   switch(mode)
  8934.   {
  8935.   case PRAGMODE_PRAGLIB: DoOutput("\n#endif\t/*  _INCLUDE_PRAGMA_%s_LIB_H  */\n",
  8936.     ShortBaseNameUpper); break;
  8937.   case PRAGMODE_PRAGSLIB: DoOutput("\n#endif\t/*  PRAGMAS_%s_LIB_H  */\n",
  8938.     ShortBaseNameUpper); break;
  8939.   case PRAGMODE_PRAGSPRAGS: DoOutput("\n#endif\t/*  PRAGMAS_%s_PRAGMA_H  */\n",
  8940.     ShortBaseNameUpper); break;
  8941.   case PRAGMODE_NONE: break;
  8942.   default: return 0;
  8943.   }
  8944.   return Output_Error;
  8945. }
  8946.  
  8947. static uint32 CreateCSTUBSFile(void)
  8948. {
  8949.   if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  8950.  
  8951.   DoOutput("#ifndef _INCLUDE_%s_CSTUBS_H\n#define _INCLUDE_%s_CSTUBS_H\n",
  8952.     ShortBaseNameUpper, ShortBaseNameUpper);
  8953.  
  8954.   if(!clibdata)
  8955.   {
  8956.     DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
  8957.   }
  8958.  
  8959.   if(HEADER)
  8960.   {
  8961.     DoOutput("\n");
  8962.     DoOutputDirect(HEADER, headersize);
  8963.   }
  8964.  
  8965.   if(!DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
  8966.   "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
  8967.     return 0;
  8968.  
  8969.   if(!CallFunc(TAGMODE_TAGS, "/%s */\n", FuncCSTUBS))
  8970.     return 0;
  8971.  
  8972.   return DoOutput("#endif\t/*  _INCLUDE_%s_CSTUBS_H  */\n",
  8973.   ShortBaseNameUpper);
  8974. }
  8975.  
  8976. static uint32 CreateLVOFile(uint32 mode)
  8977. {
  8978.   strptr data = "_LVO_I";
  8979.  
  8980.   if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
  8981.  
  8982.   if(mode == 2 || mode == 4)
  8983.     data = "_LIB_I";
  8984.  
  8985.   if(!DoOutput("\t\tIFND LIBRARIES_%s%s\nLIBRARIES_%s%s\tSET\t1\n\n",
  8986.   ShortBaseNameUpper, data, ShortBaseNameUpper, data) ||
  8987.   (HEADER && (!DoOutput("\n") || !DoOutputDirect(HEADER, headersize))) ||
  8988.   (mode <= 2 && !CallFunc(TAGMODE_NORMAL, 0, FuncLVOXDEF)) ||
  8989.   !CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVO) ||
  8990.   !DoOutput("\n\n\t\tENDC\n"))
  8991.     return 0;
  8992.  
  8993.   return 1;
  8994. }
  8995.  
  8996. static uint32 CreateLVOFilePPC(uint32 mode)
  8997. {
  8998.   if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
  8999.  
  9000.   if(!DoOutput("\t.ifndef LIBRARIES_%s_LIB_I\n.set\tLIBRARIES_%s_LIB_I,1\n\n",
  9001.   ShortBaseNameUpper, ShortBaseNameUpper))
  9002.     return 0;
  9003.   if(HEADER)
  9004.   {
  9005.     DoOutput("\n");
  9006.     DoOutputDirect(HEADER, headersize);
  9007.   }
  9008.   switch(mode)
  9009.   {
  9010.   case 0: CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCXDEF);
  9011.   case 1: CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVOPPC);
  9012.   }
  9013.   return DoOutput("\n\t.endif\n");
  9014. }
  9015.  
  9016. static uint32 CreateAsmStubs(uint32 mode, uint32 callmode)
  9017. {
  9018.   if(mode == 1 && (Flags2 & FLAG2_AUTOHEADER)) DoOutput("* %s\n\n", AUTOHEADERTEXT);
  9019.  
  9020.   /* 1 = Text, 2 = Code */
  9021.   switch(mode)
  9022.   {
  9023.   case 1:
  9024.     if(HEADER)
  9025.     {
  9026.       DoOutput("\n");
  9027.       DoOutputDirect(HEADER, headersize);
  9028.     }
  9029.     
  9030.     if(!(Flags & FLAG_ASMSECTION))
  9031.       DoOutput("\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname,
  9032.       Flags & FLAG_SMALLDATA ? "N" : "X", BaseName);
  9033.     if(!CallFunc(callmode, "\n%s", FuncAsmText))
  9034.       return 0;
  9035.     break;
  9036.   case 2:
  9037.     if(!CallFunc(callmode, 0, FuncAsmCode))
  9038.       return 0;
  9039.     break;
  9040.   }
  9041.  
  9042.   return 1;
  9043. }
  9044.  
  9045. static uint32 CreateProtoFile(uint32 Type)
  9046. {
  9047.   if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  9048.  
  9049.   DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n", ShortBaseNameUpper,
  9050.   ShortBaseNameUpper);
  9051.  
  9052.   if(HEADER)
  9053.   {
  9054.     DoOutput("\n");
  9055.     DoOutputDirect(HEADER, headersize);
  9056.   }
  9057.  
  9058.   DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
  9059.   if(Type != 5)
  9060.     DoOutput("#ifndef CLIB_%s_PROTOS_H\n"
  9061.     "#include <clib/%s_protos.h>\n#endif\n",
  9062.     ShortBaseNameUpper, ShortBaseName);
  9063.  
  9064.   if(BaseName)
  9065.   {
  9066.     DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
  9067.     if(Type == 7)
  9068.       DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
  9069.       "#endif\n");
  9070.     DoOutput("%s;\n#endif\n", BaseName);
  9071.   }
  9072.  
  9073.   if(Type != 8)
  9074.   {
  9075.     if(Type >= 6)
  9076.     {
  9077.       DoOutput("\n#ifdef " TEXT_GNUC "\n");
  9078.       if(Type == 10)
  9079.         DoOutput("#ifndef __cplusplus\n");
  9080.       DoOutput("#include <inline/%s.h>\n", ShortBaseName);
  9081.       if(Type == 10)
  9082.         DoOutput("#endif\n");
  9083.       if(Type != 7)
  9084.       {
  9085.         if(Type == 9)
  9086.           DoOutput("#elif defined(" TEXT_VBCC ")\n#if defined(__MORPHOS__) || !defined(__PPC__)\n"
  9087.           "#include <inline/%s_protos.h>\n#endif\n#else", ShortBaseName);
  9088.         else
  9089.           DoOutput("#elif !defined(" TEXT_VBCC ")");
  9090.       }
  9091.     }
  9092.     if(Type == 10)
  9093.       DoOutput("\n#ifndef __PPC__");
  9094.     if(Type != 7)
  9095.     {
  9096.       strptr str1 = "pragma", str2 = "lib";
  9097.  
  9098.       switch(Type)
  9099.       {
  9100.         case 4: str1 = "pragmas"; /* no break; */
  9101.         case 2: str2 = "pragmas"; break;
  9102.         case 3: str1 = "pragmas"; break;
  9103.         case 5: str1 = "local"; str2 = "loc"; break;
  9104.       }
  9105.       DoOutput("\n#include <%s/%s_%s.h>\n", str1, ShortBaseName, str2);
  9106.     }
  9107.     if(Type == 10)
  9108.       DoOutput("#endif\n");
  9109.     if(Type >= 6)
  9110.       DoOutput("#endif\n");
  9111.   }
  9112.  
  9113.   Flags |= FLAG_DONE;
  9114.  
  9115.   return DoOutput("\n#endif\t/*  _PROTO_%s_H  */\n", ShortBaseNameUpper);
  9116. }
  9117.  
  9118. static uint32 CreateLocalData(strptr to, uint32 callmode)
  9119. {
  9120.   if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  9121.  
  9122.   DoOutput("#ifndef _INCLUDE_PROTO_%s_LOC_H\n"
  9123.   "#define _INCLUDE_PROTO_%s_LOC_H\n",
  9124.   ShortBaseNameUpper, ShortBaseNameUpper);
  9125.  
  9126.   if(HEADER)
  9127.   {
  9128.     DoOutput("\n");
  9129.     DoOutputDirect(HEADER, headersize);
  9130.   }
  9131.  
  9132.   DoOutput("\n");
  9133.   PrintIncludes();
  9134.  
  9135.   if((Flags & FLAG_EXTERNC) &&
  9136.   !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
  9137.     return 0;
  9138.  
  9139.   if(!CallFunc(callmode, "/%s */\n", FuncLocText))
  9140.     return 0;
  9141.  
  9142.   if((Flags & FLAG_EXTERNC) &&
  9143.   !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
  9144.     return 0;
  9145.  
  9146.   DoOutput("#endif\t/*  _INCLUDE_PROTO_%s_LOC_H  */\n", ShortBaseNameUpper);
  9147.  
  9148.   sprintf(filename, "%s_loc.lib", ShortBaseName);
  9149.   if(!CloseDest(to) || !OpenDest(filename))
  9150.     return 0;
  9151.  
  9152.   CallFunc(callmode, 0, FuncLocCode);
  9153.   
  9154.   return CloseDest(filename);
  9155. }
  9156.  
  9157. static uint32 CreateInline(uint32 mode, uint32 callmode)
  9158. {
  9159.   if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  9160.  
  9161.   if(!clibdata)
  9162.   {
  9163.     DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
  9164.   }
  9165.  
  9166.   DoOutput("#ifndef _%sINLINE_%s_H\n#define _%sINLINE_%s_H\n",
  9167.   Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper,
  9168.   Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper);
  9169.  
  9170.   if(HEADER)
  9171.   {
  9172.     DoOutput("\n");
  9173.     DoOutputDirect(HEADER, headersize);
  9174.   }
  9175.  
  9176.   DoOutput("\n");
  9177.  
  9178.  
  9179.   if(mode == 6)
  9180.   {
  9181.     /* prevent loading of clib-file after inline */
  9182.     DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n#endif\n\n",
  9183.     ShortBaseNameUpper, ShortBaseNameUpper);
  9184.   }
  9185.  
  9186.   if(!mode)
  9187.   {
  9188.     if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
  9189.       DoOutput("#ifndef __PPCINLINE_MACROS_H\n"
  9190.       "#include <ppcinline/macros.h>\n#endif\n\n");
  9191.     else
  9192.       DoOutput("#ifndef __INLINE_MACROS_H\n"
  9193.       "#include <inline/macros.h>\n#endif\n\n");
  9194.     Flags |= FLAG_INLINENEW;
  9195.   }
  9196.   else if(mode <= 2)
  9197.   {
  9198.     if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
  9199.       DoOutput("#ifndef __PPCINLINE_STUB_H\n"
  9200.       "#include <ppcinline/stubs.h>\n#endif\n\n");
  9201.     else
  9202.       DoOutput("#ifndef __INLINE_STUB_H\n"
  9203.       "#include <inline/stubs.h>\n#endif\n\n");
  9204.     if(mode == 2)
  9205.       Flags |= FLAG_INLINESTUB;
  9206.   }
  9207.   else if(mode == 3)
  9208.     Flags2 |= FLAG2_INLINEMAC;
  9209.   else if(mode == 5 || mode == 6)
  9210.     PrintIncludes();
  9211.  
  9212.   if(BaseName)
  9213.   {
  9214.     if(mode && mode <= 2)
  9215.     {
  9216.       if(Flags & FLAG_MORPHOS)
  9217.         DoOutput("#include <emul/emulregs.h>\n");
  9218.       DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
  9219.       "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
  9220.       "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
  9221.       "#define BASE_PAR_DECL0 void\n#endif\n"
  9222.       "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
  9223.       "BASE_EXT_DECL0\n\n", GetBaseType(), BaseName, ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
  9224.     }
  9225.     else
  9226.       DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
  9227.       ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
  9228.   }
  9229.  
  9230.   if(mode <= 2)
  9231.   {
  9232.     if(!CallFunc(callmode, "/%s */\n", FuncInline))
  9233.       return 0;
  9234.   }
  9235.   else if(mode >= 6)
  9236.   {
  9237.     if(mode == 7)
  9238.       Flags |= FLAG_INLINENEW;
  9239.     if(!CallFunc(callmode, "/%s */\n", FuncInlineDirect))
  9240.       return 0;
  9241.   }
  9242.   else
  9243.   {
  9244.     if(!CallFunc(callmode, "/%s */\n", FuncInlineNS))
  9245.       return 0;
  9246.   }
  9247.  
  9248.   if(mode && mode <= 2 && BaseName)
  9249.     DoOutput("#undef BASE_EXT_DECL\n#undef BASE_EXT_DECL0\n"
  9250.     "#undef BASE_PAR_DECL\n#undef BASE_PAR_DECL0\n#undef %s_BASE_NAME\n\n", ShortBaseNameUpper);
  9251.  
  9252.   return DoOutput("#endif /*  _%sINLINE_%s_H  */\n",
  9253.   Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper);
  9254. }
  9255.  
  9256. static uint32 CreateGateStubs(uint32 callmode)
  9257. {
  9258.   if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  9259.  
  9260.   if(!clibdata)
  9261.   {
  9262.     DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
  9263.   }
  9264.   if(!prefix[0] && !subprefix[0])
  9265.   {
  9266.     DoError(ERR_PREFIX, 0); return 1;
  9267.   }
  9268.  
  9269.   DoOutput("#ifndef _GATESTUBS_%s_H\n#define _GATESTUBS_%s_H\n",
  9270.   ShortBaseNameUpper, ShortBaseNameUpper);
  9271.  
  9272.   DoOutput("%s\n#include <clib/%s_protos.h>\n#include <emul/emulregs.h>\n",
  9273.   premacro, ShortBaseName);
  9274.  
  9275.   if(HEADER)
  9276.   {
  9277.     DoOutput("\n");
  9278.     DoOutputDirect(HEADER, headersize);
  9279.   }
  9280.  
  9281.   if(BaseName)
  9282.   {
  9283.     DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
  9284.     "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
  9285.     "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
  9286.     "#define BASE_PAR_DECL0 void\n#endif\n"
  9287.     "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
  9288.     "BASE_EXT_DECL0\n", GetBaseType(), BaseName, ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
  9289.   }
  9290.  
  9291.   DoOutput("\n");
  9292.  
  9293.   if(!CallFunc(callmode, "/%s */\n", FuncGateStubs))
  9294.     return 0;
  9295.  
  9296.   return DoOutput("#endif /*  _GATESTUBS_%s_H  */\n", ShortBaseNameUpper);
  9297. }
  9298.  
  9299. static uint32 CreateSASPowerUP(uint32 callmode)
  9300. {
  9301.   if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  9302.  
  9303.   DoOutput("#ifndef _PPCPRAGMA_%s_H\n#define _PPCPRAGMA_%s_H\n",
  9304.   ShortBaseNameUpper, ShortBaseNameUpper);
  9305.  
  9306.   if(HEADER)
  9307.   {
  9308.     DoOutput("\n");
  9309.     DoOutputDirect(HEADER, headersize);
  9310.   }
  9311.  
  9312.   DoOutput("\n#ifdef __GNUC__\n"
  9313.   "#ifndef _PPCINLINE__%s_H\n"
  9314.   "#include <ppcinline/%s.h>\n"
  9315.   "#endif\n"
  9316.   "#else\n\n"
  9317.   "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
  9318.   "#include <ppclib/interface.h>\n"
  9319.   "#endif\n\n"
  9320.   "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
  9321.   "#include <gcclib/powerup_protos.h>\n"
  9322.   "#endif\n\n"
  9323.   "#ifndef NO_PPCINLINE_STDARG\n"
  9324.   "#define NO_PPCINLINE_STDARG\n"
  9325.   "#endif /* SAS-C PPC inlines */\n\n",
  9326.   ShortBaseNameUpper, ShortBaseName);
  9327.  
  9328.   if(BaseName)
  9329.   {
  9330.     DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
  9331.     ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
  9332.   }
  9333.  
  9334.   if(!CallFunc(callmode, "/%s */\n", FuncPowerUP))
  9335.     return 0;
  9336.  
  9337.   return DoOutput("#endif /* SAS-C PPC pragmas */\n"
  9338.   "#endif /*  _PPCPRAGMA_%s_H  */\n", ShortBaseNameUpper);
  9339. }
  9340.  
  9341. static uint32 CreateProtoPowerUP(void)
  9342. {
  9343.   if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  9344.  
  9345.   DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n",
  9346.   ShortBaseNameUpper, ShortBaseNameUpper);
  9347.  
  9348.   if(HEADER)
  9349.   {
  9350.     DoOutput("\n");
  9351.     DoOutputDirect(HEADER, headersize);
  9352.   }
  9353.  
  9354.   DoOutput("\n#include <clib/%s_protos.h>\n", ShortBaseName);
  9355.  
  9356.   if(BaseName)
  9357.   {
  9358.     DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
  9359.     DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
  9360.     "#endif\n%s;\n#endif\n", BaseName);
  9361.   }
  9362.  
  9363.   DoOutput("\n#ifdef " TEXT_GNUC "\n"
  9364.   "#ifdef __PPC__\n#include <ppcinline/%s.h>\n"
  9365.   "#else\n#include <inline/%s.h>\n#endif\n"
  9366.   "#else /* SAS-C */\n"
  9367.   "#ifdef __PPC__\n#include <ppcpragmas/%s_pragmas.h>\n"
  9368.   "#else\n#include <pragmas/%s_pragmas.h>\n#endif\n#endif\n",
  9369.   ShortBaseName, ShortBaseName, ShortBaseName, ShortBaseName);
  9370.  
  9371.   Flags |= FLAG_DONE;
  9372.  
  9373.   return DoOutput("\n#endif\t/*  _PROTO_%s_H  */\n", ShortBaseNameUpper);
  9374. }
  9375.  
  9376. static uint32 CreateFPCUnit(void)
  9377. {
  9378.   if(Flags2 & FLAG2_AUTOHEADER) DoOutput("(* %s *)\n\n", AUTOHEADERTEXT);
  9379.  
  9380.   if(!clibdata)
  9381.   {
  9382.     DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
  9383.   }
  9384.  
  9385.   DoOutput("UNIT %s;\n", ShortBaseNameUpper);
  9386.  
  9387.   if(HEADER)
  9388.   {
  9389.     DoOutput("\n");
  9390.     DoOutputDirect(HEADER, headersize);
  9391.   }
  9392.  
  9393.   DoOutput("\nINTERFACE\nUSES Exec;\n\nVAR %s : p%s;\n\n", BaseName, GetBaseTypeLib());
  9394.  
  9395.   if(!CallFunc(TAGMODE_NORMAL, 0, FuncFPCType))
  9396.     return 0;
  9397.  
  9398.   DoOutput("\nIMPLEMENTATION\n\n");
  9399.  
  9400.   if(!CallFunc(TAGMODE_NORMAL, "(%s *)\n", FuncFPCUnit))
  9401.     return 0;
  9402.  
  9403.   return DoOutput("END. (* UNIT %s *)\n", ShortBaseNameUpper);
  9404. }
  9405.  
  9406. static uint32 CreateBMAP(void)
  9407. {
  9408.   return CallFunc(TAGMODE_NORMAL, 0, FuncBMAP);
  9409. }
  9410.  
  9411. static uint32 CreateLVOLib(void)
  9412. {
  9413.   uint32 i;
  9414.  
  9415.   i = strlen(ShortBaseNameUpper);
  9416.   EndPutM32(tempbuf, HUNK_UNIT);
  9417.   EndPutM32(tempbuf+4, (i+3)>>2);
  9418.   DoOutputDirect(tempbuf, 8);
  9419.   DoOutputDirect(ShortBaseNameUpper, i);
  9420.   DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
  9421.  
  9422.   i = strlen(hunkname);
  9423.   EndPutM32(tempbuf, HUNK_NAME);
  9424.   EndPutM32(tempbuf+4, (i + 3)>>2);
  9425.   DoOutputDirect(tempbuf, 8);
  9426.   DoOutputDirect(hunkname, i);
  9427.   DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
  9428.  
  9429.   EndPutM32(tempbuf, HUNK_CODE);
  9430.   EndPutM32(tempbuf+4, 0);
  9431.   EndPutM32(tempbuf+8, HUNK_EXT);
  9432.   DoOutputDirect(tempbuf, 12);
  9433.  
  9434.   if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOLib))
  9435.     return 0;
  9436.  
  9437.   EndPutM32(tempbuf, 0);
  9438.   EndPutM32(tempbuf+4, HUNK_END);
  9439.   return DoOutputDirect(tempbuf, 8);
  9440. }
  9441.  
  9442. static uint32 CreateLVOLibPPC(void)
  9443. {
  9444.   uint8 *data = tempbuf, *data2, *data3;
  9445.  
  9446.   *(data++) = 0x7F;                                             /* eeh->e_ident[EI_MAG0] */
  9447.   *(data++) = 'E';                                              /* eeh->e_ident[EI_MAG1] */
  9448.   *(data++) = 'L';                                              /* eeh->e_ident[EI_MAG2] */
  9449.   *(data++) = 'F';                                              /* eeh->e_ident[EI_MAG3] */
  9450.   *(data++) = ELFCLASS32;                                       /* eeh->e_ident[EI_CLASS] */
  9451.   *(data++) = ELFDATA2MSB;                                      /* eeh->e_ident[EI_DATA] */
  9452.   *(data++) = EV_CURRENT;                                       /* eeh->e_ident[EI_VERSION] */
  9453.   *(data++) = 0; *(data++) = 0; *(data++) = 0;
  9454.   *(data++) = 0; *(data++) = 0; *(data++) = 0;
  9455.   *(data++) = 0; *(data++) = 0; *(data++) = 0;
  9456.   EndPutM16Inc(data, ET_REL);                                   /* eeh->e_type */
  9457.   EndPutM16Inc(data, EM_POWERPC);                               /* eeh->e_machine */
  9458.   EndPutM32Inc(data, EV_CURRENT);                               /* eeh->e_version */
  9459.   EndPutM32Inc(data, 0);                                        /* eeh->e_entry */
  9460.   EndPutM32Inc(data, 0);                                        /* eeh->e_phoff */
  9461.   data2 = data; data += 4;
  9462.   EndPutM32Inc(data, 0);                                        /* eeh->e_flags */
  9463.   EndPutM16Inc(data, 52);                                       /* eeh->e_ehsize */
  9464.   EndPutM16Inc(data, 0);                                        /* eeh->e_phentsize */
  9465.   EndPutM16Inc(data, 0);                                        /* eeh->e_phnum */
  9466.   EndPutM16Inc(data, 40);                                       /* eeh->e_shentsize */
  9467.   EndPutM16Inc(data, 4);                                        /* eeh->e_shnum */
  9468.   EndPutM16Inc(data, 1);                                        /* eeh->e_shstrndx - first table is string table */
  9469.  
  9470.   data3 = data;
  9471.   memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0\0", 28);
  9472.   data += 28;  /* 1        9        17*/
  9473.   EndPutM32(data2, data-tempbuf); /* store the entry */
  9474.  
  9475.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_name */
  9476.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_type */
  9477.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_flags */
  9478.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_addr */
  9479.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_offset */
  9480.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_size */
  9481.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_link */
  9482.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_info */
  9483.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_addralign */
  9484.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_entsize */
  9485.  
  9486.   EndPutM32Inc(data, 17);                                       /* esh[3].sh_name = .shstrtab */
  9487.   EndPutM32Inc(data, SHT_STRTAB);                               /* esh[3].sh_type */
  9488.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_flags */
  9489.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_addr */
  9490.   EndPutM32Inc(data, data3-tempbuf);                            /* esh[3].sh_offset */
  9491.   EndPutM32Inc(data, 27);                                       /* esh[3].sh_size */
  9492.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_link */
  9493.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_info */
  9494.   EndPutM32Inc(data, 1);                                        /* esh[3].sh_addralign */
  9495.   EndPutM32Inc(data, 0);                                        /* esh[3].sh_entsize */
  9496.  
  9497.   EndPutM32Inc(data, 1);                                        /* esh[4].sh_name = .symtab */
  9498.   EndPutM32Inc(data, SHT_SYMTAB);                               /* esh[4].sh_type */
  9499.   EndPutM32Inc(data, 0);                                        /* esh[4].sh_flags */
  9500.   EndPutM32Inc(data, 0);                                        /* esh[4].sh_addr */
  9501.   data2 = data;
  9502.   data += 4;                                                    /* esh[4].sh_offset */
  9503.   data += 4;                                                    /* esh[4].sh_size */
  9504.   EndPutM32Inc(data, 3);                                        /* esh[4].sh_link - the third entry is our string table */
  9505.   EndPutM32Inc(data, 1);                                        /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
  9506.   EndPutM32Inc(data, 4);                                        /* esh[4].sh_addralign */
  9507.   EndPutM32Inc(data, 16);                                       /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
  9508.  
  9509.   EndPutM32Inc(data, 9);                                        /* esh[0].sh_name = .strtab */
  9510.   EndPutM32Inc(data, SHT_STRTAB);                               /* esh[0].sh_type */
  9511.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_flags */
  9512.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_addr */
  9513.   data3 = data;
  9514.   data += 4;                                                    /* esh[0].sh_offset */
  9515.   data += 4;                                                    /* esh[0].sh_size */
  9516.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_link */
  9517.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_info */
  9518.   EndPutM32Inc(data, 1);                                        /* esh[0].sh_addralign */
  9519.   EndPutM32Inc(data, 0);                                        /* esh[0].sh_entsize */
  9520.  
  9521.   EndPutM32Inc(data2, data-tempbuf);
  9522.  
  9523.   EndPutM32Inc(data,0);
  9524.   EndPutM32Inc(data,0); /* first entry is empty */
  9525.   EndPutM32Inc(data,0);
  9526.   EndPutM32Inc(data,0);
  9527.  
  9528.   symoffset = 1; /* initial value */
  9529.   elfbufpos = data;
  9530.  
  9531.   if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCBias))
  9532.     return 0;
  9533.   EndPutM32(data2, elfbufpos-data+16);
  9534.   EndPutM32Inc(data3, elfbufpos-tempbuf);
  9535.   EndPutM32(data3, symoffset);
  9536.  
  9537.   *(elfbufpos++) = 0; /* first sym entry */
  9538.   if(!DoOutputDirect(tempbuf, elfbufpos-tempbuf))
  9539.     return 0;
  9540.  
  9541.   if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCName))
  9542.     return 0;
  9543.  
  9544.   while((symoffset++)&3)
  9545.   {
  9546.     if(!DoOutputDirect("", 1))
  9547.       return 0;
  9548.   }
  9549.  
  9550.   return 1;
  9551. }
  9552.  
  9553. static uint32 CreateVBCCInline(uint32 mode, uint32 callmode)
  9554. {
  9555.   if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  9556.  
  9557.   if(!clibdata)
  9558.   {
  9559.     DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
  9560.   }
  9561.  
  9562.   DoOutput("#ifndef _VBCCINLINE_%s_H\n#define _VBCCINLINE_%s_H\n",
  9563.   ShortBaseNameUpper, ShortBaseNameUpper);
  9564.  
  9565.   DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
  9566.  
  9567.   if(HEADER)
  9568.   {
  9569.     DoOutput("\n");
  9570.     DoOutputDirect(HEADER, headersize);
  9571.   }
  9572.  
  9573.   DoOutput("\n");
  9574.  
  9575.   if(!CallFunc(callmode, "/%s */\n", mode ? (mode == 2 ? FuncVBCCMorphInline
  9576.   : FuncVBCCWOSInline) : FuncVBCCInline))
  9577.     return 0;
  9578.  
  9579.   return DoOutput("#endif /*  _VBCCINLINE_%s_H  */\n", ShortBaseNameUpper);
  9580. }
  9581.  
  9582. static uint32 CreateVBCC(uint32 mode, uint32 callmode)
  9583. {
  9584.   uint32 res = 0;
  9585.  
  9586.   if(mode != 2 && mode != 3)
  9587.   {
  9588.     if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  9589.  
  9590.     if(HEADER)
  9591.     {
  9592.       DoOutput("\n");
  9593.       DoOutputDirect(HEADER, headersize);
  9594.     }
  9595.   }
  9596.  
  9597.   switch(mode)
  9598.   {
  9599.   case 4: res = CallFunc(callmode, 0, FuncVBCCPUPText); break;
  9600.  
  9601.   case 3: Flags |= FLAG_WOSLIBBASE; /* no break! */
  9602.   case 2: res = CallFunc(callmode, 0, FuncVBCCWOSCode); break;
  9603.  
  9604.   case 1: Flags |= FLAG_WOSLIBBASE; /* no break! */
  9605.   case 0: res = CallFunc(callmode, "\n%s", FuncVBCCWOSText); break;
  9606.   }
  9607.   return res;
  9608. }
  9609.  
  9610. static uint32 CreateVBCCPUPLib(uint32 callmode)
  9611. {
  9612.   /* output header */
  9613.   DoOutput("!<arch>\n");
  9614.  
  9615.   return CallFunc(callmode, 0, FuncVBCCPUPCode);
  9616. }
  9617.  
  9618. static uint32 CreateVBCCMorphCode(uint32 callmode)
  9619. {
  9620.   /* output header */
  9621.   DoOutput("!<arch>\n");
  9622.  
  9623.   return CallFunc(callmode, 0, FuncVBCCMorphCode);
  9624. }
  9625.  
  9626. static uint32 CreateEModule(uint32 sorted)
  9627. {
  9628.   uint32 res = 0, i;
  9629.   if(sorted)
  9630.     DoError(ERR_NO_SORTED, 0);
  9631.   else
  9632.   {
  9633.     DoOutputDirect("EMOD\0\x06", 6);
  9634.     for(res = 0; res < 2; ++res)
  9635.     {
  9636.       for(i = 0; BaseName[i]; ++i)
  9637.         DoOutput("%c", tolower(BaseName[i]));
  9638.       DoOutputDirect("\x00",1);
  9639.     }
  9640.     LastBias = BIAS_START-BIAS_OFFSET;
  9641.     CallFunc(TAGMODE_NORMAL, 0, FuncEModule);
  9642.     res = DoOutputDirect("\xFF",1);
  9643.   }
  9644.   return res;
  9645. }
  9646.  
  9647. static uint32 CreateProtoRedirect(void)
  9648. {
  9649.   Flags |= FLAG_DONE;
  9650.   return DoOutput("#ifdef NO_OBSOLETE\n"
  9651.   "#error \"Please include the proto file and not the compiler specific file!\"\n"
  9652.   "#endif\n\n#include <proto/%s.h>\n", ShortBaseName);
  9653. }
  9654.  
  9655. static uint32 CreateSFD(uint32 callmode)
  9656. {
  9657.   struct Include *inc;
  9658.   struct AmiPragma *ap;
  9659.   if(!clibdata)
  9660.   {
  9661.     DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
  9662.   }
  9663.  
  9664.   if((ap = (struct AmiPragma *) AmiPragma.First))
  9665.     LastBias = ap->Bias-BIAS_OFFSET;
  9666.   else /* only security, never used normally */
  9667.     LastBias = 0;
  9668.   CurrentABI = ABI_M68K;
  9669.  
  9670.   if(IDstring)
  9671.     DoOutput("==id %s\n", IDstring);
  9672.   else
  9673.   {
  9674.     time_t t;
  9675.     struct tm * tim;
  9676.  
  9677.     t = time(&t);
  9678.     tim = localtime(&t);
  9679.  
  9680.     DoOutput("==id $Id: %s,v 1.0 %04d/%02d/%02d %02d:%02d:%02d noname Exp $\n", filename,
  9681.     tim->tm_year+1900, tim->tm_mon+1, tim->tm_mday, tim->tm_hour, tim->tm_min,
  9682.     tim->tm_sec);
  9683.   }
  9684.  
  9685.   if(BaseName)
  9686.     DoOutput("==base _%s\n==basetype %s\n==libname %s\n", BaseName,
  9687.     GetBaseType(), GetLibraryName());
  9688.   DoOutput("==bias %ld\n==public\n", LastBias+BIAS_OFFSET);
  9689.  
  9690.   for(inc = (struct Include *) Includes.First; inc; inc = (struct Include *) inc->List.Next)
  9691.     DoOutput("==include %s\n", inc->Include);
  9692.   if(!Includes.First)
  9693.     DoOutput("==include <exec/types.h>\n");
  9694.  
  9695.   CallFunc(callmode, "%s\n", FuncSFD);
  9696.  
  9697.   return DoOutput("==end\n");
  9698. }
  9699.  
  9700. static uint32 CreateClib(uint32 callmode)
  9701. {
  9702.   if(!clibdata)
  9703.   {
  9704.     DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
  9705.   }
  9706.  
  9707.   if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
  9708.  
  9709.   DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n\n", ShortBaseNameUpper,
  9710.   ShortBaseNameUpper);
  9711.  
  9712.   if(HEADER)
  9713.   {
  9714.     DoOutput("\n");
  9715.     DoOutputDirect(HEADER, headersize);
  9716.   }
  9717.   else
  9718.   {
  9719.     strptr s = 0;
  9720.     time_t t;
  9721.     struct tm * tim;
  9722.  
  9723.     t = time(&t);
  9724.     tim = localtime(&t);
  9725.  
  9726.     if(IDstring)
  9727.     {
  9728.       s = SkipBlanks(IDstring+4);
  9729.       while(*s && *s != ' ')
  9730.         ++s;
  9731.       s=SkipBlanks(s);
  9732.     }
  9733.     if(!s || !*s)
  9734.       s = "1.0";
  9735.  
  9736.     if(Flags2 & FLAG2_SYSTEMRELEASE)
  9737.     {
  9738.       DoOutput("\n/*\n**\t$Id: %s %s\n", filename, s);
  9739.     }
  9740.     else
  9741.     {
  9742.       strptr t;
  9743.  
  9744.       t = s;
  9745.       while(*t && *t != ' ')
  9746.         ++t;
  9747.       *t = 0;
  9748.       
  9749.       DoOutput("\n/*\n**\t$VER: %s %s (%02d.%02d.%04d)\n", filename, s,
  9750.       tim->tm_mday, tim->tm_mon+1, tim->tm_year+1900);
  9751.     }
  9752.     DoOutput("**\n**\tC prototypes. For use with 32 bit integers only.\n**\n**\t");
  9753.     if(!Copyright || (Copyright && strncmp("Copyright ", Copyright, 10)))
  9754.       DoOutput("Copyright © %d ", tim->tm_year+1900);
  9755.     DoOutput("%s\n", Copyright ? Copyright : Flags2 & FLAG2_SYSTEMRELEASE ?
  9756.     "Amiga, Inc." : "");
  9757.     DoOutput("**\tAll Rights Reserved\n*/\n\n");
  9758.   }
  9759.  
  9760.   PrintIncludes();
  9761.  
  9762.   if((Flags & FLAG_EXTERNC) &&
  9763.   !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
  9764.     return 0;
  9765.  
  9766.   CallFunc(callmode, "\n/%s */\n\n", FuncClib);
  9767.  
  9768.   if((Flags & FLAG_EXTERNC) &&
  9769.   !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
  9770.     return 0;
  9771.  
  9772.   return DoOutput("\n#endif\t/*  CLIB_%s_PROTOS_H  */\n", ShortBaseNameUpper);
  9773. }
  9774.  
  9775. static uint32 CreateFD(void)
  9776. {
  9777.   LastBias = 0;
  9778.   CurrentABI = ABI_M68K;
  9779.  
  9780.   if(BaseName)
  9781.     DoOutput("##base _%s\n", BaseName);
  9782.   DoOutput("##public\n");
  9783.  
  9784.   CallFunc(TAGMODE_NORMAL, "%s\n", FuncFD);
  9785.  
  9786.   return DoOutput("##end\n");
  9787. }
  9788.  
  9789. static uint32 CreateGenAuto(strptr to, uint32 type)
  9790. {
  9791.   strptr name, btype;
  9792.   uint8 *data;
  9793.   uint32 i, verref, exitfuncref, sysref2, exitref, rel1, rel2, nameref;
  9794.   if(!(name = GetLibraryName()))
  9795.     return 0;
  9796.   btype = GetBaseType();
  9797.  
  9798.   switch(type)
  9799.   {
  9800.   case 0:
  9801.     Flags |= FLAG_DONE;
  9802.     if(!(DoOutput("#include <exec/libraries.h>\n#include <proto/exec.h>\n\n"
  9803.     "%s %s = 0;\nextern unsigned long _%sVer;\n\n"
  9804.     "void _INIT_%ld_%s(void)\n{\n  if(!(%s = %sOpenLibrary(\"%s\", _%sVer)))\n    exit(20);\n}\n\n"
  9805.     "void _EXIT_%ld_%s(void)\n{\n  if(%s)\n    CloseLibrary(%s%s);\n}\n",
  9806.     btype, BaseName, BaseName,
  9807.     priority, BaseName, BaseName, !strcmp("struct Library *", btype) ? "" : "(struct Library *) ", name, BaseName,
  9808.     priority, BaseName, BaseName, !strcmp("struct Library *", btype) ? "" : "(struct Library *) ", BaseName)))
  9809.       return 0;
  9810.     sprintf(filename, "%s_autoopenver.c", ShortBaseName);
  9811.     if(!CloseDest(to) || !OpenDest(filename))
  9812.       return 0;
  9813.     Flags |= FLAG_DONE;
  9814.     return DoOutput("unsigned long _%sVer = 0;\n", BaseName);
  9815.     break;
  9816.   case 1: /* m68k */
  9817.     Flags |= FLAG_DONE;
  9818.     i = strlen(filename)-4; /* remove .lib extension */
  9819.     EndPutM32(tempbuf, HUNK_UNIT);
  9820.     EndPutM32(tempbuf+4, (i+3)>>2);
  9821.     DoOutputDirect(tempbuf, 8);
  9822.     DoOutputDirect(filename, i);
  9823.     DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
  9824.  
  9825.     i = strlen(hunkname);
  9826.     EndPutM32(tempbuf, HUNK_NAME);
  9827.     EndPutM32(tempbuf+4, (i + 3)>>2);
  9828.     DoOutputDirect(tempbuf, 8);
  9829.     DoOutputDirect(hunkname, i);
  9830.     DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
  9831.  
  9832.     data = tempbuf+8; /* we need HUNK_CODE + size at start */
  9833.     EndPutM16Inc(data, 0x2F0E);                 /* MOVE.L A6,-(A7) */
  9834.     /* SysBase */
  9835.     if(Flags & FLAG_SMALLDATA)
  9836.     {
  9837.       EndPutM16Inc(data, 0x2C6C);                 /* MOVEA.L base(A4),A6 */
  9838.       EndPutM16Inc(data, 0);                      /* place for sysbase reference */
  9839.     }
  9840.     else
  9841.     {
  9842.       EndPutM16Inc(data, 0x2C79);                 /* MOVEA.L base,A6 */
  9843.       EndPutM32Inc(data, 0);                      /* place for sysbase reference */
  9844.     }
  9845.     verref = data-tempbuf-8+2;
  9846.     if(Flags & FLAG_SMALLDATA)
  9847.     {
  9848.       EndPutM16Inc(data, 0x202C);                 /* MOVE.L xxx(A4),D0 */
  9849.       EndPutM16Inc(data, 0);                      /* place for basevers reference */
  9850.     }
  9851.     else
  9852.     {
  9853.       EndPutM16Inc(data, 0x2039);                 /* MOVE.L xxx,D0 */
  9854.       EndPutM32Inc(data, 0);                      /* place for basevers reference */
  9855.     }
  9856.     EndPutM32Inc(data, 0x43FA0030 + ((Flags2 & FLAG2_SMALLCODE) ? 0 : 2) + ((Flags & FLAG_SMALLDATA) ? 0 : 6));
  9857.     EndPutM32Inc(data, 0x4EAEFDD8);               /* JSR _LVOOpenLibrary(A6) */
  9858.  
  9859.     rel1 = data-tempbuf-8+2;
  9860.     if(Flags & FLAG_SMALLDATA)
  9861.     {
  9862.       EndPutM16Inc(data, 0x2940);                 /* MOVE.L D0,xxx(A4) */
  9863.       EndPutM16Inc(data, 0);
  9864.     }
  9865.     else
  9866.     {
  9867.       EndPutM16Inc(data, 0x23C0);                 /* MOVE.L D0,xxx */
  9868.       EndPutM32Inc(data, 0);
  9869.     }
  9870.     EndPutM16Inc(data, 0x660A + ((Flags2 & FLAG2_SMALLCODE) ? 0 : 2)); /* BNE.B .lib */
  9871.     EndPutM32Inc(data, 0x48780014);               /* PEA 20 */
  9872.  
  9873.     exitfuncref = data-tempbuf-8+2;
  9874.     if(Flags2 & FLAG2_SMALLCODE)
  9875.     {
  9876.       EndPutM16Inc(data, 0x4EBA);                 /* JSR _exit(PC) */
  9877.       EndPutM16Inc(data, 0);                      /* place for base reference */
  9878.     }
  9879.     else
  9880.     {
  9881.       EndPutM16Inc(data, 0x4EB9);                 /* JSR _exit */
  9882.       EndPutM32Inc(data, 0);                      /* place for base reference */
  9883.     }
  9884.     EndPutM16Inc(data, 0x584F);                   /* ADDQ.W, #4,A7 */
  9885.     EndPutM16Inc(data, 0x2C5F);                   /* MOVE.L (A7)+,A6 */
  9886.     EndPutM16Inc(data,0x4E75);                    /* RTS */
  9887.     exitref = data-tempbuf-8;
  9888.     
  9889.     EndPutM16Inc(data, 0x2F0E);                   /* MOVE.L A6,-(A7) */
  9890.     sysref2 = data-tempbuf-8+2;
  9891.     /* SysBase */
  9892.     if(Flags & FLAG_SMALLDATA)
  9893.     {
  9894.       EndPutM16Inc(data, 0x2C6C);                 /* MOVEA.L base(A4),A6 */
  9895.       EndPutM16Inc(data, 0);                      /* place for sysbase reference */
  9896.     }
  9897.     else
  9898.     {
  9899.       EndPutM16Inc(data, 0x2C79);                 /* MOVEA.L base,A6 */
  9900.       EndPutM32Inc(data, 0);                      /* place for sysbase reference */
  9901.     }
  9902.     rel2 = data-tempbuf-8+2;
  9903.     if(Flags & FLAG_SMALLDATA)
  9904.     {
  9905.       EndPutM16Inc(data, 0x202C);                 /* MOVE.L xxx(A4),D0 */
  9906.       EndPutM16Inc(data, 0);                      /* place for base reference */
  9907.     }
  9908.     else
  9909.     {
  9910.       EndPutM16Inc(data, 0x2039);                 /* MOVE.L xxx,D0 */
  9911.       EndPutM32Inc(data, 0);                      /* place for base reference */
  9912.     }
  9913.     EndPutM16Inc(data, 0x6606);                   /* BNE.B .nolib */
  9914.     EndPutM16Inc(data, 0x2240);                   /* MOVEA.L D0,A1 */
  9915.  
  9916.     EndPutM32Inc(data, 0x4EAEFE62);               /* JSR _LVOCloseLibrary(A6) */
  9917.     EndPutM16Inc(data, 0x2C5F);                   /* MOVE.L (A7)+,A6 */
  9918.     EndPutM16Inc(data,0x4E75);                    /* RTS */
  9919.     nameref = data-tempbuf-8;
  9920.     memcpy(data, name, strlen(name));
  9921.     data += strlen(name);
  9922.     do { *(data++) = 0; } while((data-tempbuf)&3);
  9923.  
  9924.     EndPutM32(tempbuf, HUNK_CODE);
  9925.     EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
  9926.     DoOutputDirect(tempbuf, (size_t)(data-tempbuf)&(~3));
  9927.  
  9928.     if(Flags & FLAG_SMALLDATA)
  9929.     {
  9930.       EndPutM32(tempbuf, HUNK_DREL16);
  9931.     }
  9932.     else
  9933.     {
  9934.       EndPutM32(tempbuf, HUNK_ABSRELOC32);
  9935.     }
  9936.     EndPutM32(tempbuf+4, 2); /* 2 entries */
  9937.     EndPutM32(tempbuf+8, 1); /* to hunk 1 */
  9938.     EndPutM32(tempbuf+12, rel1); /* address 0 */
  9939.     EndPutM32(tempbuf+16, rel2); /* address 0 */
  9940.     EndPutM32(tempbuf+20, 0); /* end of reloc hunk */
  9941.     DoOutputDirect(tempbuf, 24);
  9942.  
  9943.     /* extern references */
  9944.     EndPutM32(tempbuf, HUNK_EXT);
  9945.     DoOutputDirect(tempbuf, 4);
  9946.  
  9947.     OutputXREF2(4, sysref2, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "_SysBase");
  9948.     OutputXREF(verref, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "__%sVer", BaseName);
  9949.     OutputXREF(exitfuncref, (Flags2 & FLAG2_SMALLCODE ? EXT_DEXT16 : EXT_REF32), "_exit");
  9950.     OutputXDEF(0, "__INIT_%ld_%s", priority, BaseName);
  9951.     OutputXDEF(exitref, "__EXIT_%ld_%s", priority, BaseName);
  9952.     OutputXDEF(nameref, "%sname", ShortBaseName);
  9953.     EndPutM32(tempbuf, 0); /* ext end */
  9954.     DoOutputDirect(tempbuf, 4);
  9955.  
  9956.     if(!(Flags & FLAG_NOSYMBOL))
  9957.     {
  9958.       EndPutM32(tempbuf, HUNK_SYMBOL);
  9959.       DoOutputDirect(tempbuf, 4);
  9960.       OutputSYMBOL(0, "__INIT_%ld_%s", priority, BaseName);
  9961.       OutputSYMBOL(exitref, "__EXIT_%ld_%s", priority, BaseName);
  9962.       OutputSYMBOL(nameref, "%sname", ShortBaseName);
  9963.       EndPutM32(tempbuf, 0);
  9964.       DoOutputDirect(tempbuf, 4);
  9965.     }
  9966.  
  9967.     EndPutM32(tempbuf, HUNK_END);
  9968.     DoOutputDirect(tempbuf, 4);
  9969.  
  9970.     i = strlen(datahunkname);
  9971.     EndPutM32(tempbuf, HUNK_NAME);
  9972.     EndPutM32(tempbuf+4, (i + 3)>>2);
  9973.     DoOutputDirect(tempbuf, 8);
  9974.     DoOutputDirect(datahunkname, i);
  9975.     DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
  9976.  
  9977.     EndPutM32(tempbuf, HUNK_BSS);
  9978.     EndPutM32(tempbuf+4, 1);
  9979.     DoOutputDirect(tempbuf, 8);
  9980.  
  9981.     EndPutM32(tempbuf, HUNK_EXT);
  9982.     DoOutputDirect(tempbuf, 4);
  9983.     OutputXDEF(0, "_%s", BaseName);
  9984.     EndPutM32(tempbuf, 0); /* ext end */
  9985.     DoOutputDirect(tempbuf, 4);
  9986.  
  9987.     if(!(Flags & FLAG_NOSYMBOL))
  9988.     {
  9989.       EndPutM32(tempbuf, HUNK_SYMBOL);
  9990.       DoOutputDirect(tempbuf, 4);
  9991.       OutputSYMBOL(0, "_%s", BaseName);
  9992.       EndPutM32(tempbuf, 0);
  9993.       DoOutputDirect(tempbuf, 4);
  9994.     }
  9995.  
  9996.     EndPutM32(tempbuf, HUNK_END);
  9997.     DoOutputDirect(tempbuf, 4);
  9998.  
  9999.     sprintf(filename, "%s_autoopenver", ShortBaseName);
  10000.     i = strlen(filename);
  10001.     EndPutM32(tempbuf, HUNK_UNIT);
  10002.     EndPutM32(tempbuf+4, (i+3)>>2);
  10003.     DoOutputDirect(tempbuf, 8);
  10004.     DoOutputDirect(filename, i);
  10005.     DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
  10006.  
  10007.     i = strlen(datahunkname);
  10008.     EndPutM32(tempbuf, HUNK_NAME);
  10009.     EndPutM32(tempbuf+4, (i + 3)>>2);
  10010.     DoOutputDirect(tempbuf, 8);
  10011.     DoOutputDirect(datahunkname, i);
  10012.     DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
  10013.  
  10014.     EndPutM32(tempbuf, HUNK_BSS);
  10015.     EndPutM32(tempbuf+4, 1);
  10016.     DoOutputDirect(tempbuf, 8);
  10017.  
  10018.     EndPutM32(tempbuf, HUNK_EXT);
  10019.     DoOutputDirect(tempbuf, 4);
  10020.     OutputXDEF(0, "_%sVer", BaseName);
  10021.     EndPutM32(tempbuf, 0); /* ext end */
  10022.     DoOutputDirect(tempbuf, 4);
  10023.  
  10024.     if(!(Flags & FLAG_NOSYMBOL))
  10025.     {
  10026.       EndPutM32(tempbuf, HUNK_SYMBOL);
  10027.       DoOutputDirect(tempbuf, 4);
  10028.       OutputSYMBOL(0, "_%sVer", BaseName);
  10029.       EndPutM32(tempbuf, 0);
  10030.       DoOutputDirect(tempbuf, 4);
  10031.     }
  10032.  
  10033.     EndPutM32(tempbuf, HUNK_END);
  10034.     return DoOutputDirect(tempbuf, 4);
  10035.  
  10036.     break;
  10037.   }
  10038.   return 0;
  10039. }
  10040.  
  10041. /* ------------------------------------------------------------------ */
  10042.  
  10043. static uint32 GetName(struct NameList *t, struct ShortListRoot *p, uint32 args)
  10044. {
  10045.   struct NameList *p2 = (struct NameList *) p->First;
  10046.   struct AmiPragma ap;
  10047.   ap.FuncName = t->NormName;
  10048.   ap.NumArgs = 1;
  10049.   ap.Args[0].ArgName = (args ? "args" : "tags");
  10050.   if(!MakeTagFunction(&ap))
  10051.     return 0;
  10052.  
  10053.   if(!ap.TagName)
  10054.     return 0;
  10055.  
  10056.   while(p2 && (!p2->PragName || strcmp(p2->PragName, ap.TagName)))
  10057.    p2 = (struct NameList *) p2->List.Next;
  10058.  
  10059.   if(!p2)
  10060.     return 0;
  10061.  
  10062.   t->Type = (args ? NTP_ARGS : NTP_TAGS);
  10063.   t->PragName = ap.TagName;
  10064.   RemoveItem(p, (struct ShortList *) p2);
  10065.  
  10066. #ifdef DEBUG_OLD
  10067.   printf("GetName: name matches - %s _ %s\n", t->NormName, t->PragName);
  10068. #endif
  10069.  
  10070.   return 1;
  10071. }
  10072.  
  10073. static void OptimizeFDData(struct PragData *pd)
  10074. {
  10075. #ifdef DEBUG_OLD
  10076.   printf("OptimizeFDData\n");
  10077. #endif
  10078.  
  10079.   while(pd)
  10080.   {
  10081.     if(pd->NumNames > 1)
  10082.     {
  10083.       struct ShortListRoot n = {0,0,0}, p = {0,0,0};
  10084.       struct NameList *t;
  10085.       while(pd->Name.First)     /* sorts in AmiCall and TagCall */
  10086.       {
  10087.         t = (struct NameList *) pd->Name.First;
  10088.  
  10089.         RemoveItem(&pd->Name, (struct ShortList *) t);
  10090.         AddItem(t->PragName ? &p : &n, (struct ShortList *) t);
  10091.       }
  10092.  
  10093.       if(p.First)
  10094.       {
  10095.         t = (struct NameList *) n.First;
  10096.         while(p.First && t)
  10097.         {
  10098.           if(!GetName(t, &p, 0))
  10099.           {
  10100.             GetName(t, &p, 1);
  10101.           }
  10102.           if(t->PragName)
  10103.           {
  10104.             struct NameList *t2 = (struct NameList *) t->List.Next;
  10105.             RemoveItem(&n, (struct ShortList *)t);
  10106.             AddItem(&pd->Name, (struct ShortList *) t);
  10107.             t = t2;
  10108.           }
  10109.           else
  10110.             t = (struct NameList *) t->List.Next;
  10111.         }
  10112.         while(p.First)
  10113.         {
  10114.           if(n.First)
  10115.           {
  10116.             t = (struct NameList *) n.First;
  10117.             t->PragName = ((struct NameList *)(p.First))->PragName;
  10118.             RemoveItem(&n, (struct ShortList *) t);
  10119. #ifdef DEBUG_OLD
  10120.   printf("OptimizeFDData: names together - %s _ %s\n", t->NormName, t->PragName);
  10121. #endif
  10122.             t->Type = NTP_UNKNOWN;
  10123.           }
  10124.           else
  10125.           {
  10126.             uint32 i;
  10127.  
  10128.             t = (struct NameList *) p.First;
  10129.             i = strlen(t->PragName);
  10130.             t->NormName = DupString(t->PragName, i+1);
  10131.             t->NormName[i++] = 'A';
  10132.             t->NormName[i] = 0;
  10133.             t->Type = NTP_TAGS;
  10134. #ifdef DEBUG_OLD
  10135.   printf("OptimizeFDData: NormName created - %s _ %s\n", t->NormName, t->PragName);
  10136. #endif
  10137.           }
  10138.  
  10139.           AddItem(&pd->Name, (struct ShortList *) t);
  10140.           RemoveItem(&p, p.First);
  10141.         }
  10142.       }
  10143.  
  10144.       AddItem(&pd->Name, n.First); /* add left NormNames */
  10145.     }
  10146.     pd = (struct PragData *) pd->List.Next;
  10147.   }
  10148. }
  10149.  
  10150. static uint32 MakeFD(struct PragList *pl)
  10151. {
  10152.   struct PragData *pd = (struct PragData *) pl->Data.First;
  10153.   uint32 bias;
  10154.  
  10155. #ifdef DEBUG_OLD
  10156.   printf("MakeFD\n");
  10157. #endif
  10158.   bias = pd->Bias;
  10159.  
  10160.   OptimizeFDData(pd);
  10161. #ifdef DEBUG_OLD
  10162.   printf("MakeFD: after Optimizing\n");
  10163. #endif
  10164.   DoOutput("##base _%s\n##bias %ld\n##public\n", pl->Basename, bias);
  10165.  
  10166.   while(pd && Output_Error)
  10167.   {
  10168.     struct NameList *n = (struct NameList *) pd->Name.First;
  10169.  
  10170.     if(bias != pd->Bias)
  10171.       DoOutput("##bias %ld\n", (bias = pd->Bias));
  10172.  
  10173.     while(n)
  10174.     {
  10175.       strptr lastpar = "last";
  10176.       uint32 i;
  10177.  
  10178.       if(n->Type == NTP_TAGS)
  10179.         lastpar = "tags";
  10180.       else if(n->Type == NTP_ARGS)
  10181.         lastpar = "args";
  10182.  
  10183.       DoOutput("%s("/*)*/,n->NormName);
  10184.       if(!pd->NumArgs)
  10185.         DoOutput(/*(*/")()\n");
  10186.       else
  10187.       {
  10188.         for(i = 0; i < pd->NumArgs-1; ++i)
  10189.           DoOutput("par%ld,",i+1);
  10190.         DoOutput(/*(*/"%s)("/*)*/, lastpar);
  10191.         for(i = 0; i < pd->NumArgs-1; ++i)
  10192.           DoOutput("%s,", RegNames[pd->ArgReg[i]]);
  10193.         DoOutput(/*(*/"%s)\n", RegNames[pd->ArgReg[i]]);
  10194.  
  10195.         if(n->Type == NTP_UNKNOWN)
  10196.         {
  10197.           uint32 i;
  10198.           for(i = 0; n->NormName[i] == n->PragName[i]; ++i)
  10199.             ;
  10200.           DoOutput("*tagcall");
  10201.           if(n->NormName[i])
  10202.             DoOutput("-%s", n->NormName+i);
  10203.           if(n->PragName[i])
  10204.             DoOutput("+%s", n->PragName+i);
  10205.  
  10206.           DoOutput("\n");
  10207.         }
  10208.       }
  10209.       if((n = (struct NameList *) n->List.Next))
  10210.         DoOutput("##bias %ld\n", pd->Bias);
  10211.       Flags |= FLAG_DONE;
  10212.     }
  10213.  
  10214.     pd = (struct PragData *)pd->List.Next; bias += BIAS_OFFSET;
  10215.   }
  10216.  
  10217.   DoOutput("##end\n");
  10218.  
  10219.   return Output_Error;
  10220. }
  10221.  
  10222. static uint32 AddFDData(struct ShortListRoot *pls, struct FDData *fd)
  10223. {
  10224.   struct NameList *t;
  10225.   struct PragList *pl = (struct PragList *) pls->First;
  10226.   struct PragData *pd;
  10227.  
  10228.   while(pl && strcmp(pl->Basename, fd->Basename))
  10229.     pl = (struct PragList *) pl->List.Next;
  10230.  
  10231.   if(!pl)
  10232.   {
  10233. #ifdef DEBUG_OLD
  10234.   printf("AddFDData: New PragList - %s\n", fd->Basename);
  10235. #endif
  10236.     if(!(pl = (struct PragList *) NewItem(pls)))
  10237.       return 100;
  10238.     pl->Basename = fd->Basename;
  10239.     pl->Data.Size = sizeof(struct PragData);
  10240.     AddItem(pls, (struct ShortList *) pl);
  10241.   }
  10242.  
  10243.   if((pd = (struct PragData *) pl->Data.First))
  10244.   {
  10245.     while(pd->List.Next && ((struct PragData *) pd->List.Next)->Bias
  10246.     <= fd->Bias)
  10247.       pd = (struct PragData *) pd->List.Next;
  10248.   }
  10249.  
  10250.   if(!pd || pd->Bias != fd->Bias)
  10251.   {
  10252.     struct PragData *pd2;
  10253. #ifdef DEBUG_OLD
  10254.   printf("AddFDData: New PragData - %ld, %ld\n", fd->Bias, fd->NumArgs);
  10255. #endif
  10256.     if(!(pd2 = (struct PragData *) NewItem(&pl->Data)))
  10257.       return 100;
  10258.     pd2->Bias = fd->Bias;
  10259.     memcpy(pd2->ArgReg, fd->ArgReg, MAXREG);
  10260.     pd2->NumArgs = fd->NumArgs;
  10261.     pd2->Name.Size = sizeof(struct NameList);
  10262.     if(!pd)
  10263.       AddItem(&pl->Data, (struct ShortList *) pd2);
  10264.     else if(pd->Bias > fd->Bias) /* Insert at start */
  10265.     {
  10266.       pd2->List.Next = pl->Data.First;
  10267.       pl->Data.First = (struct ShortList *) pd2;
  10268.     }
  10269.     else /* Insert the entry */
  10270.     {
  10271.       pd2->List.Next = pd->List.Next;
  10272.       pd->List.Next = (struct ShortList *) pd2;
  10273.     }
  10274.     pd = pd2;
  10275.   }
  10276.   else
  10277.   {
  10278.     uint32 i = fd->NumArgs;
  10279.     if(fd->NumArgs != pd->NumArgs)
  10280.     {
  10281. #ifdef DEBUG_OLD
  10282.   printf("ArgNum %ld != %ld\n", fd->NumArgs, pd->NumArgs);
  10283. #endif
  10284.       return ERR_DIFFERENT_TO_PREVIOUS;
  10285.     }
  10286.  
  10287.     while(i--)
  10288.     {
  10289.       if(fd->ArgReg[i] != pd->ArgReg[i])
  10290.       {
  10291. #ifdef DEBUG_OLD
  10292.   printf("ArgReg %lx != %lx\n", fd->ArgReg[i], pd->ArgReg[i]);
  10293. #endif
  10294.         return ERR_DIFFERENT_TO_PREVIOUS;
  10295.       }
  10296.     }
  10297.   }
  10298.  
  10299.   t = (struct NameList *) pd->Name.First;       /* skips same names */
  10300.   while(t && (!(fd->Mode ? t->PragName : t->NormName) ||
  10301.   strcmp(fd->Name, fd->Mode ? t->PragName : t->NormName)))
  10302.     t = (struct NameList *) t->List.Next;
  10303.  
  10304.   if(t)
  10305.     return 0;
  10306.  
  10307.   if(!(t = (struct NameList *) NewItem(&pd->Name)))
  10308.     return 100;
  10309.   if(fd->Mode)
  10310.     t->PragName = fd->Name;
  10311.   else
  10312.     t->NormName = fd->Name;
  10313.   AddItem(&pd->Name, (struct ShortList *) t);
  10314.   ++(pd->NumNames);
  10315. #ifdef DEBUG_OLD
  10316.   printf("AddFDData: New NameList - %s\n", fd->Name);
  10317. #endif
  10318.   return 0;
  10319. }
  10320.  
  10321. static string GetHexValue(string data)
  10322. {
  10323.   if(data >= 'a')
  10324.     return (string) (data - 'a' + 10);
  10325.   else if(data >= 'A')
  10326.     return (string) (data - 'A' + 10);
  10327.   else
  10328.     return (string) (data - '0');
  10329. }
  10330.  
  10331. static string GetDoubleHexValue(strptr data)
  10332. {
  10333.   return (string)((GetHexValue(*data)<<4)+GetHexValue(data[1]));
  10334. }
  10335.  
  10336. static uint32 GetLibData(struct FDData *fd)
  10337. {
  10338.   uint32 i;
  10339.   fd->Name = SkipBlanks(in.pos);
  10340.   in.pos = SkipName(fd->Name); *(in.pos++) = 0;
  10341.   in.pos = SkipBlanks(in.pos);
  10342.   fd->Bias = strtoul(in.pos, 0, 16);
  10343.   in.pos = SkipName(SkipBlanks(SkipName(in.pos)));
  10344.   if((fd->NumArgs = GetHexValue(*(--in.pos))) > MAXREGNF - 2)
  10345.     return ERR_TO_MUCH_ARGUMENTS;
  10346.   --in.pos; /* skips return register */
  10347.   for(i = 0; i < fd->NumArgs; ++i)
  10348.   {
  10349.     if((fd->ArgReg[i] = GetHexValue(*(--in.pos))) > REG_A5)
  10350.       return ERR_EXPECTED_REGISTER_NAME;
  10351.   }
  10352.   return 0;
  10353. }
  10354.  
  10355. static uint32 GetFlibData(struct FDData *fd)
  10356. {
  10357.   uint32 i;
  10358.   fd->Name = SkipBlanks(in.pos);
  10359.   in.pos = SkipName(fd->Name); *(in.pos++) = 0;
  10360.   in.pos = SkipBlanks(in.pos);
  10361.   fd->Bias = strtoul(in.pos, 0, 16);
  10362.   in.pos = SkipName(SkipBlanks(SkipName(in.pos))) - 2;
  10363.   if((fd->NumArgs = GetDoubleHexValue(in.pos)) > MAXREG-2)
  10364.     return ERR_TO_MUCH_ARGUMENTS;
  10365.   in.pos -= 2; /* skips return register */
  10366.   for(i = 0; i < fd->NumArgs; ++i)
  10367.   {
  10368.     in.pos -= 2;
  10369.     if((fd->ArgReg[i] = GetDoubleHexValue(in.pos)) >= MAXREG)
  10370.       return ERR_EXPECTED_REGISTER_NAME;
  10371.     else if(fd->ArgReg[i] >= REG_FP0 && (Flags & FLAG_NOFPU))
  10372.       return ERR_FLOATARG_NOT_ALLOWED;
  10373.   }
  10374.   return 0;
  10375. }
  10376.  
  10377. static uint32 GetAmiData(struct FDData *fd)
  10378. {
  10379.   strptr endptr;
  10380.   in.pos = SkipBlanks(in.pos);
  10381.   if(*in.pos != '('/*)*/)
  10382.     return ERR_EXPECTED_OPEN_BRACKET;
  10383.   fd->Basename = ++in.pos;
  10384.   in.pos = SkipBlanks(endptr = SkipName(in.pos));
  10385.   if(*in.pos != ',')
  10386.     return ERR_EXPECTED_COMMA;
  10387.   *endptr = 0;
  10388.   in.pos = SkipBlanks(++in.pos);
  10389.   if(!strncmp(in.pos, "0x", 2))
  10390.     fd->Bias = strtoul(in.pos+2, 0, 16);
  10391.   else
  10392.     fd->Bias = strtoul(in.pos, 0, 10);
  10393.  
  10394.   in.pos = SkipBlanks(SkipName(in.pos));
  10395.   if(*in.pos != ',')
  10396.     return ERR_EXPECTED_COMMA;
  10397.   fd->Name = in.pos = SkipBlanks(++in.pos);
  10398.   in.pos = SkipBlanks(endptr = SkipName(in.pos));
  10399.   if(*in.pos != '('/*)*/)
  10400.     return ERR_EXPECTED_OPEN_BRACKET;
  10401.   *endptr = 0;
  10402.   in.pos = SkipBlanks(++in.pos);
  10403.   if(*in.pos == /*(*/')')
  10404.     return 0;
  10405.   --in.pos;
  10406.   while(*in.pos != /*(*/')')
  10407.   {
  10408.     uint32 i;
  10409.     in.pos = SkipBlanks(in.pos+1);
  10410.  
  10411.     for(i = 0; i < REG_FP0; i++)
  10412.       if(!strnicmp(RegNames[i], in.pos, 2))
  10413.         break;
  10414.     if(i == REG_FP0)
  10415.     {
  10416.       for(; i < MAXREG; i++)
  10417.         if(!strnicmp(RegNames[i], in.pos, 3))
  10418.           break;
  10419.     }
  10420.  
  10421.     if(i == MAXREG)
  10422.       return ERR_EXPECTED_REGISTER_NAME;
  10423.     else if(i >= REG_FP0 && (Flags & FLAG_NOFPU))
  10424.       return ERR_FLOATARG_NOT_ALLOWED;
  10425.  
  10426.     fd->ArgReg[fd->NumArgs] = i; ++fd->NumArgs;
  10427.  
  10428.     if(fd->NumArgs > MAXREG-2)
  10429.       return ERR_TO_MUCH_ARGUMENTS;
  10430.  
  10431.     in.pos = SkipBlanks(in.pos+(i >= REG_FP0 ? 3 : 2));
  10432.  
  10433.     if(*in.pos != ',' && *in.pos != /*(*/')')
  10434.       return ERR_EXPECTED_CLOSE_BRACKET;
  10435.   }
  10436.   in.pos = SkipBlanks(in.pos+1);
  10437.   if(*in.pos != /*(*/')')
  10438.     return ERR_EXPECTED_CLOSE_BRACKET;
  10439.   return 0;
  10440. }
  10441.  
  10442. static uint32 CreateFDFile(void)
  10443. {
  10444.   struct ShortListRoot pl = {0, 0, sizeof(struct PragList)};
  10445.   uint32 linenum, err = 0, skip;
  10446.   strptr ptr, p2;
  10447.  
  10448.   ptr = p2 = args.infile;
  10449.   while(*p2)
  10450.   {
  10451.     if(*p2 == '/' || *p2 == ':' || *p2 == '\\')
  10452.       ptr = p2+1;
  10453.     ++p2;
  10454.   }
  10455.   for(p2 = ptr; *p2 && *p2 != '_' && *p2 != '.'; ++p2)
  10456.     ;
  10457.   if(p2 != ptr)
  10458.   {
  10459.     ShortBaseName = ptr;
  10460.     *p2 = '\0';
  10461.   }
  10462.  
  10463.   for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
  10464.   {
  10465.     in.pos = SkipBlanks(in.pos);
  10466.     if(!strncmp("#pragma", in.pos, 7))
  10467.     {
  10468.       struct FDData fd;
  10469.  
  10470.       skip = 0;
  10471.       memset(&fd, 0, sizeof(struct FDData));
  10472.  
  10473.       in.pos = SkipBlanks(in.pos+7);
  10474.       if(!strncmp("tagcall", in.pos, 7))
  10475.       {
  10476.         fd.Mode = 1;
  10477.         in.pos = SkipBlanks(in.pos+7);
  10478.         if(*in.pos == '(' /*)*/)                /* Storm method */
  10479.           err = GetAmiData(&fd);
  10480.         else                                    /* SAS method */
  10481.         {
  10482.           fd.Basename = in.pos;
  10483.           in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
  10484.           err = GetLibData(&fd);
  10485.         }
  10486.       }
  10487.       else if(!strncmp("amicall", in.pos, 7))   /* Storm method */
  10488.       {
  10489.         in.pos += 7;
  10490.         err = GetAmiData(&fd);
  10491.       }
  10492.       else if(!strncmp("libcall", in.pos, 7))   /* SAS method */
  10493.       {
  10494.         fd.Basename = SkipBlanks(in.pos+7);
  10495.         in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
  10496.         err = GetLibData(&fd);
  10497.       }
  10498.       else if(!strncmp("flibcall", in.pos, 8))  /* SAS method */
  10499.       {
  10500.         fd.Basename = SkipBlanks(in.pos+8);
  10501.         in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
  10502.         err = GetFlibData(&fd);
  10503.       }
  10504.       else if(!strncmp("syscall", in.pos, 7))   /* SAS method */
  10505.       {
  10506.         fd.Basename = "SysBase";
  10507.         err = GetLibData(&fd);
  10508.       }
  10509.       else
  10510.         skip = 1;
  10511.  
  10512.       if(err)
  10513.         DoError(err, linenum);
  10514.       else if(skip)
  10515.         ;
  10516.       else if((err = AddFDData(&pl, &fd)))
  10517.       {
  10518.         if(err != 100)
  10519.           DoError(err, linenum);
  10520.         return 0;
  10521.       }
  10522.     }
  10523.     while(*(in.pos++))  /* jumps to first char of next line */
  10524.       ;
  10525.   }
  10526.  
  10527.   if(pl.First)
  10528.   {
  10529.     struct PragList *p = (struct PragList *) pl.First;
  10530.     if(!p->List.Next)
  10531.     {
  10532.       strptr text, to;
  10533.       uint32 i;
  10534.  
  10535.       if(ShortBaseName)
  10536.       {
  10537.         text = ShortBaseName; i = strlen(text);
  10538.       }
  10539.       else
  10540.       {
  10541.         text = p->Basename; i = strlen(text)-4;
  10542.       }
  10543.  
  10544.       to = DupString(text, i + sizeof(FDFILEEXTENSION) - 1);
  10545.       memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
  10546.       if(!OpenDest(to))
  10547.         return 0;
  10548.       
  10549.       err = MakeFD(p);
  10550.       CloseDest(to);
  10551.       if(!err)
  10552.         return 0;
  10553.     }
  10554.     else
  10555.     {
  10556.       while(p)
  10557.       {
  10558.         strptr to;
  10559.         uint32 i;
  10560.         i = strlen(p->Basename) - 4;
  10561.         to = DupString(p->Basename, i + sizeof(FDFILEEXTENSION) - 1);
  10562.         memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
  10563.         if(!OpenDest(to))
  10564.           return 0;
  10565.         i = MakeFD(p);
  10566.         CloseDest(to);
  10567.         if(!i)
  10568.           return 0;
  10569.         p = (struct PragList *) p->List.Next;
  10570.       }
  10571.     }
  10572.   }
  10573.  
  10574.   return 1;
  10575. }
  10576.  
  10577. #ifdef FD2PRAGMA_READARGS
  10578. #include <proto/dos.h>
  10579.  
  10580. #define PARAM   "FROM=INFILE/A,SPECIAL/N,MODE/N,"                       \
  10581.                 "TO/K,ABI/K,CLIB/K,COPYRIGHT/K,HEADER/K,HUNKNAME/K,"    \
  10582.                 "BASENAME/K,LIBTYPE/K,LIBNAME/K,PRIORITY/N/K,"          \
  10583.                 "PREFIX/K,SUBPREFIX/K,PREMACRO/K,"                      \
  10584.                 "AUTOHEADER/S,COMMENT/S,EXTERNC/S,FPUONLY/S,"           \
  10585.                 "NEWSYNTAX/S,"                                          \
  10586.                 "NOFPU/S,NOPPC/S,NOPPCREGNAME/S,NOSYMBOL/S,"            \
  10587.                 "ONLYCNAMES/S,OPT040/S,PPCONLY/S,"                      \
  10588.                 "PRIVATE/S,SECTION/S,SMALLCODE/S,SMALLDATA/S,"          \
  10589.                 "SMALLTYPES/S,SORTED/S,SYSTEMRELEASE/S,USESYSCALL/S,"   \
  10590.                 "VOIDBASE/S"
  10591.  
  10592. struct AmiArg
  10593. {
  10594.   strptr INFILE;
  10595.   uint32* SPECIAL;
  10596.   uint32* MODE;
  10597.   strptr  TO;
  10598.   strptr  ABI;
  10599.   strptr  CLIB;
  10600.   strptr  COPYRIGHT;
  10601.   strptr  HEADER;
  10602.   strptr  HUNKNAME;
  10603.   strptr  BASENAME;
  10604.   strptr  LIBTYPE;
  10605.   strptr  LIBNAME;
  10606.   uint32* PRIORITY;
  10607.   strptr  PREFIX;
  10608.   strptr  SUBPREFIX;
  10609.   strptr  PREMACRO;
  10610.   uint32  AUTOHEADER;
  10611.   uint32  COMMENT;
  10612.   uint32  EXTERNC;
  10613.   uint32  FPUONLY;
  10614.   uint32  NEWSYNTAX;
  10615.   uint32  NOFPU;
  10616.   uint32  NOPPC;
  10617.   uint32  NOPPCREGNAME;
  10618.   uint32  NOSYMBOL;
  10619.   uint32  ONLYCNAMES;
  10620.   uint32  OPT040;
  10621.   uint32  PPCONLY;
  10622.   uint32  PRIVATE;
  10623.   uint32  SECTION;
  10624.   uint32  SMALLCODE;
  10625.   uint32  SMALLDATA;
  10626.   uint32  SMALLTYPES;
  10627.   uint32  SORTED;
  10628.   uint32  SYSTEMRELEASE;
  10629.   uint32  USESYSCALL;
  10630.   uint32  VOIDBASE;
  10631. };
  10632.  
  10633. static const strptr helptext =
  10634. "INFILE:  the input file which should be used\n"
  10635. "SPECIAL: 1 - Aztec compiler (xxx_lib.h,     MODE 2, AMICALL)\n"
  10636. "\t 2 - DICE compiler  (xxx_pragmas.h, MODE 3, LIBCALL)\n"
  10637. "\t 3 - SAS compiler   (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
  10638. "\t 4 - MAXON compiler (xxx_lib.h,     MODE 1, AMICALL)\n"
  10639. "\t 5 - STORM compiler (xxx_lib.h,     MODE 1, AMITAGS,AMICALL)\n"
  10640. "\t 6 - pragma for all compilers [default]\n"
  10641. "\t 7 - all compilers with pragma to inline redirect for GCC\n"
  10642. "\t10 - stub-functions for C - C text\n"
  10643. "\t11 - stub-functions for C - assembler text\n"
  10644. "\t12 - stub-functions for C - link library\n"
  10645. "\t13 - defines and link library for local library base (register call)\n"
  10646. "\t14 - defines and link library for local library base (stack call)\n"
  10647. "\t15 - stub-functions for Pascal - assembler text\n"
  10648. "\t16 - stub-functions for Pascal - link library\n"
  10649. "\t17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
  10650. "\t18 - module for AmigaE\n"
  10651. "\t20 - assembler lvo _lvo.i file\n"
  10652. "\t21 - assembler lvo _lib.i file\n"
  10653. "\t22 - assembler lvo _lvo.i file no XDEF\n"
  10654. "\t23 - assembler lvo _lib.i file no XDEF\n"
  10655. "\t24 - assembler lvo link library\n"
  10656. "\t30 - proto file with pragma/..._lib.h call\n"
  10657. "\t31 - proto file with pragma/..._pragmas.h call\n"
  10658. "\t32 - proto file with pragmas/..._lib.h call\n"
  10659. "\t33 - proto file with pragmas/..._pragmas.h call\n"
  10660. "\t34 - proto file with local/..._loc.h call\n"
  10661. "\t35 - proto file for all compilers (VBCC stubs)\n"
  10662. "\t36 - proto file for GNU-C compiler only\n"
  10663. "\t37 - proto file without lib definitions\n"
  10664. "\t38 - proto file for all compilers (VBCC inline)\n"
  10665. "\t39 - proto file with special PPC related checks\n"
  10666. "\t40 - GCC inline file (preprocessor based)\n"
  10667. "\t41 - GCC inline file (old type - inline based)\n"
  10668. "\t42 - GCC inline file (library stubs)\n"
  10669. "\t43 - GCC inline file (new style - macro)\n"
  10670. "\t44 - GCC inline file (new style - inline)\n"
  10671. "\t45 - GCC inline file (new style - inline with include lines)\n"
  10672. "\t46 - GCC inline file (preprocessor based, direct)\n"
  10673. "\t47 - GCC inline file (new style, direct)\n"
  10674. "\t50 - GCC inline files for PowerUP (preprocessor based)\n"
  10675. "\t51 - GCC inline files for PowerUP (old type - inline based)\n"
  10676. "\t52 - GCC inline files for PowerUP (library stubs)\n"
  10677. "\t53 - SAS-C include file for PowerUP\n"
  10678. "\t54 - Proto file for PowerUP\n"
  10679. "\t60 - FPC pascal unit text\n"
  10680. "\t70 - VBCC inline files\n"
  10681. "\t71 - VBCC WOS stub-functions - assembler text\n"
  10682. "\t72 - VBCC WOS stub-functions - assembler text (libbase)\n"
  10683. "\t73 - VBCC WOS stub-functions - link library\n"
  10684. "\t74 - VBCC WOS stub-functions - link library (libbase)\n"
  10685. "\t75 - VBCC PowerUP stub-functions - assembler text\n"
  10686. "\t76 - VBCC PowerUP stub-functions - link library\n"
  10687. "\t77 - VBCC WOS inline files\n"
  10688. "\t78 - VBCC MorphOS stub-functions - link library\n"
  10689. "\t79 - VBCC old inline files\n"
  10690. "\t80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
  10691. "\t81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
  10692. "\t82 - pragma/proto redirect (xxx.h, GCC)\n"
  10693. "\t83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
  10694. "\t90 - stub-functions for C - assembler text (multiple files)\n"
  10695. "\t91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
  10696. "\t92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
  10697. "\t93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
  10698. "       100 - PPC assembler lvo file\n"
  10699. "       101 - PPC assembler lvo file no XDEF\n"
  10700. "       102 - PPC assembler lvo ELF link library\n"
  10701. "       103 - PPC assembler lvo EHF link library\n"
  10702. "       104 - PPC V.4-ABI assembler file\n"
  10703. "       105 - PPC V.4-ABI assembler file no XDEF\n"
  10704. "       106 - PPC V.4-ABI assembler lvo ELF link library\n"
  10705. "       107 - PPC V.4-ABI assembler lvo EHF link library\n"
  10706. "       110 - FD file\n"
  10707. "       111 - CLIB file\n"
  10708. "       112 - SFD file\n"
  10709. "       120 - VBCC auto libopen files (C source)\n"
  10710. "       121 - VBCC auto libopen files (m68k link library)\n"
  10711. "       122 - VBCC MorphOS inline files\n"
  10712. "       130 - GCC inline files for MorphOS (preprocessor based)\n"
  10713. "       131 - GCC inline files for MorphOS (old type - inline based)\n"
  10714. "       132 - GCC inline files for MorphOS (library stubs)\n"
  10715. "       133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
  10716. "       134 - MorphOS gate stubs\n"
  10717. "       135 - MorphOS gate stubs (prelib)\n"
  10718. "       136 - MorphOS gate stubs (postlib)\n"
  10719. "       137 - MorphOS gate stubs (reglib, prelib)\n"
  10720. "       138 - MorphOS gate stubs (reglib, postlib)\n"
  10721. "       200 - FD file (source is a pragma file!)\n"
  10722. "MODE:          SPECIAL 1-7:\n"
  10723. "                 1: _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
  10724. "                 2: _PRAGMAS_..._LIB_H definition method\n"
  10725. "                 3: _PRAGMAS_..._PRAGMAS_H definition method\n"
  10726. "                 4: no definition\n"
  10727. "               SPECIAL 11-14,40-45,50-53,70-76,78,90-91,111-112,122,130-138:\n"
  10728. "                 1: all functions, normal interface\n"
  10729. "                 2: only tag-functions, tagcall interface\n"
  10730. "                 3: all functions, normal and tagcall interface [default]\n"
  10731. "TO:            the destination directory (self creation of filename)\n"
  10732. "ABI:           set ABI type (m68k|ppc|ppc0|ppc2)\n"
  10733. "CLIB:          name of the prototypes file in clib directory\n"
  10734. "COPYRIGHT:     the copyright text for CLIB files\n"
  10735. "HEADER:        inserts given file into header of created file (\"\" is scan)\n"
  10736. "HUNKNAME:      use this name for HUNK_NAME instead of default 'text'\n"
  10737. "BASENAME:      name of library base without '_'\n"
  10738. "LIBNAME:       name of the library (.e.g. dos.library)\n"
  10739. "LIBTYPE:       type of base library structure\n"
  10740. "PRIORITY:      priority for auto open files\n"
  10741. "PREFIX:        MorphOS gate prefix\n"
  10742. "SUBPREFIX:     MorphOS gate sub prefix\n"
  10743. "PREMACRO:      MorphOS gate file start macro\n"
  10744. "Switches:\n"
  10745. "AUTOHEADER     add the typical automatic generated header\n"
  10746. "COMMENT:       copy comments found in input file\n"
  10747. "EXTERNC:       add a #ifdef __cplusplus ... statement to pragma file\n"
  10748. "FPUONLY:       work only with functions using FPU register arguments\n"
  10749. "NEWSYNTAX:     uses new Motorola syntax for asm files\n"
  10750. "NOFPU:         disable usage of FPU register arguments\n"
  10751. "NOPPC:         disable usage of PPC-ABI functions\n"
  10752. "NOPPCREGNAME:  do not add 'r' to PPC register names\n"
  10753. "NOSYMBOL:      prevents creation of SYMBOL hunks for link libraries\n"
  10754. "ONLYCNAMES:    do not create C++ or ASM names\n"
  10755. "OPT040:        optimize for 68040, do not use MOVEM for stubs\n"
  10756. "PPCONLY:       only use PPC-ABI functions\n"
  10757. "PRIVATE:       includes private declared functions\n"
  10758. "SECTION:       add section statements to asm texts\n"
  10759. "SMALLCODE:     generate small code link libraries or assembler text\n"
  10760. "SMALLDATA:     generate small data link libraries or assembler text\n"
  10761. "SMALLTYPES:    allow 8 and 16 bit types in registers\n"
  10762. "SORTED:        sort generated files by name and not by bias value\n"
  10763. "SYSTEMRELEASE: special handling of comments for system includes\n"
  10764. "USESYSCALL:    uses syscall pragma instead of libcall SysBase\n"
  10765. "VOIDBASE:      library bases are of type void *\n";
  10766.  
  10767. /* print the help text */
  10768. static void printhelp(void)
  10769. {
  10770.   printf("%s\n%s\n\n%s", version+6, PARAM, helptext);
  10771.   exit(20);
  10772. }
  10773.  
  10774. /* initializes the arguments and starts argument parsing */
  10775. static void GetArgs(int argc, char **argv)
  10776. {
  10777.   struct RDArgs *rda;
  10778.   struct AmiArg amiargs;
  10779.   int res = 0;
  10780.  
  10781.   if((rda = (struct RDArgs *) AllocDosObject(DOS_RDARGS, 0)))
  10782.   {
  10783.     rda->RDA_ExtHelp = helptext;
  10784.     memset(&amiargs, 0, sizeof(struct AmiArg));
  10785.     if(ReadArgs(PARAM, (int32 *) &amiargs, rda))
  10786.     {
  10787.       int l;
  10788.       strptr d, s;
  10789.  
  10790.       l = strlen(amiargs.TO ? amiargs.TO : "") + 1
  10791.         + strlen(amiargs.CLIB ? amiargs.CLIB : "") + 1
  10792.         + strlen(amiargs.HEADER ? amiargs.HEADER :  "") + 1
  10793.         + strlen(amiargs.ABI ? amiargs.ABI : "") + 1
  10794.         + strlen(amiargs.HUNKNAME ? amiargs.HUNKNAME : "") + 1
  10795.         + strlen(amiargs.BASENAME ? amiargs.BASENAME : "") + 1
  10796.         + strlen(amiargs.LIBTYPE ? amiargs.LIBTYPE : "") + 1
  10797.         + strlen(amiargs.LIBNAME ? amiargs.LIBNAME : "") + 1
  10798.         + strlen(amiargs.COPYRIGHT ? amiargs.COPYRIGHT : "") + 1
  10799.         + strlen(amiargs.PREFIX ? amiargs.PREFIX : "") + 1
  10800.         + strlen(amiargs.SUBPREFIX ? amiargs.SUBPREFIX : "") + 1
  10801.         + strlen(amiargs.PREMACRO ? amiargs.PREMACRO : "") + 1
  10802.         + strlen(amiargs.INFILE) + 1;
  10803.       if((d = AllocListMem(l)))
  10804.       {
  10805.         res = 1;
  10806.  
  10807.         s = amiargs.INFILE;
  10808.         args.infile = d; while(*s) *(d++) = *(s++); *(d++) = 0;
  10809.         if((s = amiargs.TO))
  10810.         {
  10811.           args.to = d; while(*s) *(d++) = *(s++); *(d++) = 0;
  10812.         }
  10813.         if((s = amiargs.HEADER))
  10814.         {
  10815.           args.header = d; while(*s) *(d++) = *(s++); *(d++) = 0;
  10816.         }
  10817.         if((s = amiargs.CLIB))
  10818.         {
  10819.           args.clib = d; while(*s) *(d++) = *(s++); *(d++) = 0;
  10820.         }
  10821.         if((s = amiargs.HUNKNAME))
  10822.         {
  10823.           hunkname = d; while(*s) *(d++) = *(s++); *(d++) = 0;
  10824.         }
  10825.         if((s = amiargs.BASENAME))
  10826.         {
  10827.           Flags |= FLAG_BASENAME;
  10828.           BaseName = d; while(*s) *(d++) = *(s++); *(d++) = 0;
  10829.         }
  10830.         if((s = amiargs.LIBTYPE))
  10831.         {
  10832.           Flags2 |= FLAG2_LIBTYPE;
  10833.           libtype = d; while(*s) *(d++) = *(s++); *(d++) = 0;
  10834.         }
  10835.         if((s = amiargs.LIBNAME))
  10836.         {
  10837.           Flags2 |= FLAG2_LIBNAME;
  10838.           libname = d; while(*s) *(d++) = *(s++); *(d++) = 0;
  10839.         }
  10840.         if((s = amiargs.PREFIX))
  10841.         {
  10842.           prefix = d; while(*s) *(d++) = *(s++); *(d++) = 0;
  10843.         }
  10844.         if((s = amiargs.SUBPREFIX))
  10845.         {
  10846.           subprefix = d; while(*s) *(d++) = *(s++); *(d++) = 0;
  10847.         }
  10848.         if((s = amiargs.PREMACRO))
  10849.         {
  10850.           premacro = d; while(*s) *(d++) = *(s++); *(d++) = 0;
  10851.         }
  10852.         if((s = amiargs.COPYRIGHT))
  10853.         {
  10854.           Copyright = d; while(*s) *(d++) = *(s++); *(d++) = 0;
  10855.         }
  10856.         if((s = amiargs.ABI))
  10857.         {
  10858.           defabi = d; while(*s) *(d++) = *(s++); *d = 0;
  10859.         }
  10860.         if(amiargs.EXTERNC)      Flags ^= FLAG_EXTERNC;
  10861.         if(amiargs.PRIVATE)      Flags ^= FLAG_PRIVATE;
  10862.         if(amiargs.NEWSYNTAX)    Flags ^= FLAG_NEWSYNTAX;
  10863.         if(amiargs.SMALLDATA)    Flags ^= FLAG_SMALLDATA;
  10864.         if(amiargs.SMALLCODE)    Flags2 ^= FLAG2_SMALLCODE;
  10865.         if(amiargs.SMALLTYPES)   Flags2 ^= FLAG2_SMALLTYPES;
  10866.         if(amiargs.USESYSCALL)   Flags ^= FLAG_SYSCALL;
  10867.         if(amiargs.OPT040)       Flags ^= FLAG_NOMOVEM;
  10868.         if(amiargs.NOFPU)        Flags ^= FLAG_NOFPU;
  10869.         if(amiargs.FPUONLY)      Flags ^= FLAG_FPUONLY;
  10870.         if(amiargs.NOPPC)        Flags ^= FLAG_NOPPC;
  10871.         if(amiargs.NOSYMBOL)     Flags ^= FLAG_NOSYMBOL;
  10872.         if(amiargs.PPCONLY)      Flags ^= FLAG_PPCONLY;
  10873.         if(amiargs.SECTION)      Flags ^= FLAG_ASMSECTION;
  10874.         if(amiargs.COMMENT)      Flags ^= FLAG_DOCOMMENT;
  10875.         if(amiargs.SORTED)       Flags ^= FLAG_SORTED;
  10876.         if(amiargs.ONLYCNAMES)   Flags ^= FLAG_ONLYCNAMES;
  10877.         if(amiargs.SYSTEMRELEASE) Flags2 ^= FLAG2_SYSTEMRELEASE;
  10878.         if(amiargs.VOIDBASE)     Flags2 ^= FLAG2_VOIDBASE;
  10879.         if(amiargs.NOPPCREGNAME) PPCRegPrefix = "";
  10880.         if(amiargs.AUTOHEADER)   Flags2 ^= FLAG2_AUTOHEADER;
  10881.         if(amiargs.SPECIAL)
  10882.           args.special = *amiargs.SPECIAL;
  10883.         if(amiargs.MODE)
  10884.           args.mode = *amiargs.MODE;
  10885.         if(amiargs.PRIORITY)
  10886.           priority = *amiargs.PRIORITY;
  10887.       }
  10888.       FreeArgs(rda);
  10889.     }
  10890.     else
  10891.       PrintFault(IoErr(), 0);
  10892.     FreeDosObject(DOS_RDARGS, rda);
  10893.   }
  10894.  
  10895.   if(!res)
  10896. /*    printhelp(); */
  10897.     exit(20);
  10898. }
  10899.  
  10900. #else
  10901. static const strptr helptext =
  10902. " -h,--help\n"
  10903. " -i,--infile   <input filename>\n"
  10904. " -s,--special  <number>\n"
  10905. " -m,--mode     <number>\n"
  10906. " -t,--to       <destination directory>\n"
  10907. " -a,--abi      <m68k|ppc|ppc0|ppc2>\n"
  10908. " -c,--clib     <clib prototypes filename>\n"
  10909. " -h,--header   <header file or \"\">\n"
  10910. " -i,--libname  <name of library>\n"
  10911. " -n,--hunkname <name of HUNK_NAME, default is 'text'>\n"
  10912. " -b,--basename <name of library base without '_'>\n"
  10913. " -l,--libtype  <name of base library type>\n"
  10914. " -p,--priority <priority for auto open files>\n"
  10915. " -r,--copyright<copyright text>\n"
  10916. "    --prefix   <MorphOS gate prefix>\n"
  10917. "    --subprefix<MorphOS gate sub prefix>\n"
  10918. "    --premacro <MorphOS gate file start macro>\n"
  10919. "\n"
  10920. "Switches:\n"
  10921. "--autoheader    add the typical automatic generated header\n"
  10922. "--comment       copy comments found in input file\n"
  10923. "--externc       add a #ifdef __cplusplus ... statement to pragma file\n"
  10924. "--fpuonly       work only with functions using FPU register arguments\n"
  10925. "--newsyntax     uses new Motorola syntax for asm files\n"
  10926. "--nofpu         disable usage of FPU register arguments\n"
  10927. "--noppc         disable usage of PPC-ABI functions\n"
  10928. "--noppcregname  do not add 'r' to PPC register names\n"
  10929. "--nosymbol      prevents creation of SYMBOL hunks for link libraries\n"
  10930. "--onlycnames    do not create C++ or ASM names\n"
  10931. "--opt040        optimize for 68040, do not use MOVEM for stubs\n"
  10932. "--ppconly       only use PPC-ABI functions\n"
  10933. "--private       includes private declared functions\n"
  10934. "--section       add section statements to asm texts\n"
  10935. "--smallcode     generate small code link libraries or assembler text\n"
  10936. "--smalldata     generate small data link libraries or assembler text\n"
  10937. "--smalltypes    allow 8 and 16 bit types in registers\n"
  10938. "--sorted        sort generated files by name and not by bias value\n"
  10939. "--systemrelease special handling of comments for system includes\n"
  10940. "--usesyscall    uses syscall pragma instead of libcall SysBase\n"
  10941. "--voidbase      library bases are of type void *\n"
  10942. "\n"
  10943. "special: 1 - Aztec compiler (xxx_lib.h,     MODE 2, AMICALL)\n"
  10944. "         2 - DICE compiler  (xxx_pragmas.h, MODE 3, LIBCALL)\n"
  10945. "         3 - SAS compiler   (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
  10946. "         4 - MAXON compiler (xxx_lib.h,     MODE 1, AMICALL)\n"
  10947. "         5 - STORM compiler (xxx_lib.h,     MODE 1, AMITAGS,AMICALL)\n"
  10948. "         6 - pragma for all compilers [default]\n"
  10949. "         7 - all compilers with pragma to inline redirect for GCC\n"
  10950. "        10 - stub-functions for C - C text\n"
  10951. "        11 - stub-functions for C - assembler text\n"
  10952. "        12 - stub-functions for C - link library\n"
  10953. "        13 - defines and link library for local library base (register call)\n"
  10954. "        14 - defines and link library for local library base (stack call)\n"
  10955. "        15 - stub-functions for Pascal - assembler text\n"
  10956. "        16 - stub-functions for Pascal - link library\n"
  10957. "        17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
  10958. "        18 - module for AmigaE\n"
  10959. "        20 - assembler lvo _lvo.i file\n"
  10960. "        21 - assembler lvo _lib.i file\n"
  10961. "        22 - assembler lvo _lvo.i file no XDEF\n"
  10962. "        23 - assembler lvo _lib.i file no XDEF\n"
  10963. "        24 - assembler lvo link library\n"
  10964. "        30 - proto file with pragma/..._lib.h call\n"
  10965. "        31 - proto file with pragma/..._pragmas.h call\n"
  10966. "        32 - proto file with pragmas/..._lib.h call\n"
  10967. "        33 - proto file with pragmas/..._pragmas.h call\n"
  10968. "        34 - proto file with local/..._loc.h call\n"
  10969. "        35 - proto file for all compilers (VBCC stubs)\n"
  10970. "        36 - proto file for GNU-C compiler only\n"
  10971. "        37 - proto file without lib definitions\n"
  10972. "        38 - proto file for all compilers (VBCC inline)\n"
  10973. "        39 - proto file with special PPC related checks\n"
  10974. "        40 - GCC inline file (preprocessor based)\n"
  10975. "        41 - GCC inline file (old type - inline based)\n"
  10976. "        42 - GCC inline file (library stubs)\n"
  10977. "        43 - GCC inline file (new style - macro)\n"
  10978. "        44 - GCC inline file (new style - inline)\n"
  10979. "        45 - GCC inline file (new style - inline with include lines)\n"
  10980. "        46 - GCC inline file (preprocessor based, direct)\n"
  10981. "        47 - GCC inline file (new style, direct)\n"
  10982. "        50 - GCC inline files for PowerUP (preprocessor based)\n"
  10983. "        51 - GCC inline files for PowerUP (old type - inline based)\n"
  10984. "        52 - GCC inline files for PowerUP (library stubs)\n"
  10985. "        53 - SAS-C include file for PowerUP\n"
  10986. "        54 - Proto file for PowerUP\n"
  10987. "        60 - FPC pascal unit text\n"
  10988. "        70 - VBCC inline files\n"
  10989. "        71 - VBCC WOS stub-functions - assembler text\n"
  10990. "        72 - VBCC WOS stub-functions - assembler text (libbase)\n"
  10991. "        73 - VBCC WOS stub-functions - link library\n"
  10992. "        74 - VBCC WOS stub-functions - link library (libbase)\n"
  10993. "        75 - VBCC PowerUP stub-functions - assembler text\n"
  10994. "        76 - VBCC PowerUP stub-functions - link library\n"
  10995. "        77 - VBCC WOS inline files\n"
  10996. "        78 - VBCC MorphOS stub-functions - link library\n"
  10997. "        79 - VBCC old inline files\n"
  10998. "        80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
  10999. "        81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
  11000. "        82 - pragma/proto redirect (xxx.h, GCC)\n"
  11001. "        83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
  11002. "        90 - stub-functions for C - assembler text (multiple files)\n"
  11003. "        91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
  11004. "        92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
  11005. "        93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
  11006. "       100 - PPC assembler lvo file\n"
  11007. "       101 - PPC assembler lvo file no XDEF\n"
  11008. "       102 - PPC assembler lvo ELF link library\n"
  11009. "       103 - PPC assembler lvo EHF link library\n"
  11010. "       104 - PPC V.4-ABI assembler file\n"
  11011. "       105 - PPC V.4-ABI assembler file no XDEF\n"
  11012. "       106 - PPC V.4-ABI assembler lvo ELF link library\n"
  11013. "       107 - PPC V.4-ABI assembler lvo EHF link library\n"
  11014. "       110 - FD file\n"
  11015. "       111 - CLIB file\n"
  11016. "       112 - SFD file\n"
  11017. "       120 - VBCC auto libopen files (C source)\n"
  11018. "       121 - VBCC auto libopen files (m68k link library)\n"
  11019. "       122 - VBCC MorphOS inline files\n"
  11020. "       130 - GCC inline files for MorphOS (preprocessor based)\n"
  11021. "       131 - GCC inline files for MorphOS (old type - inline based)\n"
  11022. "       132 - GCC inline files for MorphOS (library stubs)\n"
  11023. "       133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
  11024. "       134 - MorphOS gate stubs\n"
  11025. "       135 - MorphOS gate stubs (prelib)\n"
  11026. "       136 - MorphOS gate stubs (postlib)\n"
  11027. "       137 - MorphOS gate stubs (reglib, prelib)\n"
  11028. "       138 - MorphOS gate stubs (reglib, postlib)\n"
  11029. "       200 - FD file (source is a pragma file!)\n"
  11030. "mode:    SPECIAL 1-7\n"
  11031. "         1 - _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
  11032. "         2 - _PRAGMAS_..._LIB_H definition method\n"
  11033. "         3 - _PRAGMAS_..._PRAGMAS_H definition method\n"
  11034. "         4 - no definition\n"
  11035. "         SPECIAL 11-14,40-45,50-53,70-76,78,90-93,111-112,122,130-138:\n"
  11036. "         1 - all functions, normal interface\n"
  11037. "         2 - only tag-functions, tagcall interface\n"
  11038. "         3 - all functions, normal and tagcall interface [default]\n";
  11039.  
  11040. /* print the help text */
  11041. static void printhelp(void)
  11042. {
  11043.   printf("%s\n%s", version+6, helptext);
  11044.   exit(20);
  11045. }
  11046.  
  11047. struct ArgData
  11048. {
  11049.   strptr ArgName;
  11050.   uint8  ArgChar;
  11051.   uint8  ArgNameLen;
  11052.   uint8  ArgNum;
  11053. };
  11054.  
  11055. enum ArgNums {
  11056. ARG_HELP, ARG_INFILE, ARG_SPECIAL, ARG_MODE, ARG_TO, ARG_CLIB, ARG_ABI, ARG_COPYRIGHT,
  11057. ARG_HEADER, ARG_HUNKNAME, ARG_BASENAME, ARG_LIBTYPE,
  11058. ARG_COMMENT, ARG_EXTERNC, ARG_FPUONLY, ARG_NEWSYNTAX, ARG_NOFPU, ARG_NOPPC,
  11059. ARG_NOSYMBOL, ARG_ONLYCNAMES, ARG_OPT040, ARG_PPCONLY, ARG_PRIVATE, ARG_SECTION,
  11060. ARG_SMALLDATA, ARG_SORTED, ARG_USESYSCALL, ARG_NOPPCREGNAME,
  11061. ARG_SYSTEMRELEASE, ARG_PRIORITY, ARG_LIBNAME, ARG_SMALLCODE, ARG_VOIDBASE,
  11062. ARG_PREFIX, ARG_SUBPREFIX, ARG_PREMACRO, ARG_SMALLTYPES, ARG_AUTOHEADER
  11063. };
  11064.  
  11065. /* argument definition array */
  11066. static const struct ArgData argtexts[] = {
  11067. {"help", 'h', 4, ARG_HELP},
  11068. {"infile", 'i', 6, ARG_INFILE},
  11069. {"special", 's', 7, ARG_SPECIAL},
  11070. {"mode", 'm', 4, ARG_MODE},
  11071. {"to", 't', 2, ARG_TO},
  11072. {"clib", 'c', 4, ARG_CLIB},
  11073. {"abi", 'a', 3, ARG_ABI},
  11074. {"copyright", 'r', ARG_COPYRIGHT},
  11075. {"header", 'h', 6, ARG_HEADER},
  11076. {"hunkname", 'n', 8, ARG_HUNKNAME},
  11077. {"basename", 'b', 8, ARG_BASENAME},
  11078. {"libtype", 'l', 7, ARG_LIBTYPE},
  11079. {"libname", 'i', 7, ARG_LIBNAME},
  11080. {"priority", 'p', 8, ARG_PRIORITY},
  11081. {"autoheader", 0, 10, ARG_AUTOHEADER},
  11082. {"comment", 0, 7, ARG_COMMENT},
  11083. {"externc", 0, 7, ARG_EXTERNC},
  11084. {"fpuonly", 0, 7, ARG_FPUONLY},
  11085. {"newsyntax", 0, 9, ARG_NEWSYNTAX},
  11086. {"nofpu", 0, 5, ARG_NOFPU},
  11087. {"noppc", 0, 5, ARG_NOPPC},
  11088. {"noppcregname", 0, 12, ARG_NOPPCREGNAME},
  11089. {"nosymbol", 0, 8, ARG_NOSYMBOL},
  11090. {"onlycnames", 0, 10, ARG_ONLYCNAMES},
  11091. {"opt040", 0, 6, ARG_OPT040},
  11092. {"ppconly", 0, 7, ARG_PPCONLY},
  11093. {"private", 0, 7, ARG_PRIVATE},
  11094. {"section", 0, 7, ARG_SECTION},
  11095. {"smalldata", 0, 9, ARG_SMALLDATA},
  11096. {"smalltypes", 0, 10, ARG_SMALLTYPES},
  11097. {"smallcode", 0, 9, ARG_SMALLCODE},
  11098. {"sorted", 0, 6, ARG_SORTED},
  11099. {"systemrelease", 13, ARG_SYSTEMRELEASE},
  11100. {"usesyscall", 0, 10, ARG_USESYSCALL},
  11101. {"voidbase", 0, 8, ARG_VOIDBASE},
  11102. {"prefix", 0, 6, ARG_PREFIX},
  11103. {"subprefix", 0, 9, ARG_SUBPREFIX},
  11104. {"premacro", 0, 8, ARG_PREMACRO},
  11105. {0,0,0,0}, /* end marker */
  11106. };
  11107.  
  11108. /* parse on argument entry, returns number of used entries, 0 for error, -1 for error without error printout */
  11109. static uint32 ParseArgEntry(uint32 argc, strptr *argv)
  11110. {
  11111.   uint32 numentries = 1, l;
  11112.   strptr a, b;
  11113.   const struct ArgData *ad;
  11114.  
  11115.   if((*argv)[0] != '-' || !(*argv)[1])
  11116.     return 0;
  11117.  
  11118.   ad = argtexts;
  11119.   while(ad->ArgName)
  11120.   {
  11121.     if((*argv)[1] == ad->ArgChar || ((*argv)[1] == '-' && !strncmp(ad->ArgName, (*argv)+2, ad->ArgNameLen)))
  11122.       break;
  11123.     ++ad;
  11124.   }
  11125.   if(!ad->ArgName)
  11126.     return 0;
  11127.   switch(ad->ArgNum)
  11128.   {
  11129.   case ARG_HELP: printhelp(); break;
  11130.   case ARG_EXTERNC:        Flags ^= FLAG_EXTERNC; break;
  11131.   case ARG_PRIVATE:        Flags ^= FLAG_PRIVATE; break;
  11132.   case ARG_NEWSYNTAX:      Flags ^= FLAG_NEWSYNTAX; break;
  11133.   case ARG_SMALLDATA:      Flags ^= FLAG_SMALLDATA; break;
  11134.   case ARG_SMALLCODE:      Flags2 ^= FLAG2_SMALLCODE; break;
  11135.   case ARG_SMALLTYPES:     Flags2 ^= FLAG2_SMALLTYPES; break;
  11136.   case ARG_USESYSCALL:     Flags ^= FLAG_SYSCALL; break;
  11137.   case ARG_OPT040:         Flags ^= FLAG_NOMOVEM; break;
  11138.   case ARG_NOFPU:          Flags ^= FLAG_NOFPU; break;
  11139.   case ARG_FPUONLY:        Flags ^= FLAG_FPUONLY; break;
  11140.   case ARG_NOPPC:          Flags ^= FLAG_NOPPC; break;
  11141.   case ARG_NOSYMBOL:       Flags ^= FLAG_NOSYMBOL; break;
  11142.   case ARG_PPCONLY:        Flags ^= FLAG_PPCONLY; break;
  11143.   case ARG_SECTION:        Flags ^= FLAG_ASMSECTION; break;
  11144.   case ARG_COMMENT:        Flags ^= FLAG_DOCOMMENT; break;
  11145.   case ARG_SORTED:         Flags ^= FLAG_SORTED; break;
  11146.   case ARG_ONLYCNAMES:     Flags ^= FLAG_ONLYCNAMES; break;
  11147.   case ARG_SYSTEMRELEASE:  Flags2 ^= FLAG2_SYSTEMRELEASE; break;
  11148.   case ARG_VOIDBASE:       Flags2 ^= FLAG2_VOIDBASE; break;
  11149.   case ARG_AUTOHEADER:     Flags2 ^= FLAG2_AUTOHEADER; break;
  11150.   case ARG_NOPPCREGNAME:   PPCRegPrefix = "";
  11151.   default:
  11152.     a = *argv+((*argv)[1] == '-' ? ad->ArgNameLen+2 : 2);
  11153.     if(!(*a))
  11154.     {
  11155.       if(argc > 1) { a = argv[1]; numentries = 2; }
  11156.       else { a = 0; numentries = 0;}
  11157.     }
  11158.     else if(*a == '=')
  11159.       ++a;
  11160.     if(a)
  11161.     {
  11162.       if(*a == '\"')
  11163.       {
  11164.         l = strlen(++a);
  11165.         if(a[l-1] == '\"')
  11166.           a[--l] = 0; /* remove second " */
  11167.       }
  11168.       switch(ad->ArgNum)
  11169.       {
  11170.       case ARG_INFILE: args.infile = a; break;
  11171.       case ARG_COPYRIGHT: Copyright = a; break;
  11172.       case ARG_TO: args.to = a; break;
  11173.       case ARG_ABI: defabi = a; break;
  11174.       case ARG_CLIB: args.clib = a; break;
  11175.       case ARG_HEADER: args.header = a; break;
  11176.       case ARG_HUNKNAME: hunkname = a; break;
  11177.       case ARG_PREFIX: prefix = a; break;
  11178.       case ARG_SUBPREFIX: subprefix = a; break;
  11179.       case ARG_PREMACRO: premacro = a; break;
  11180.       case ARG_LIBTYPE: libtype = a; Flags2 |= FLAG2_LIBTYPE; break;
  11181.       case ARG_LIBNAME: libname = a; Flags2 |= FLAG2_LIBNAME; break;
  11182.       case ARG_BASENAME: BaseName = a; Flags |= FLAG_BASENAME; break;
  11183.       case ARG_SPECIAL:
  11184.         args.special = strtoul(a, &b, 10);
  11185.         if(*b)
  11186.           numentries = 0;
  11187.         break;
  11188.       case ARG_PRIORITY:
  11189.         priority = strtoul(a, &b, 10);
  11190.         if(*b)
  11191.           numentries = 0;
  11192.         break;
  11193.       case ARG_MODE:
  11194.         args.mode = strtoul(a, &b, 10);
  11195.         if(*b || args.mode < 1 || args.mode > 3)
  11196.           numentries = 0;
  11197.         break;
  11198.       }
  11199.     }
  11200.   }
  11201.   return numentries;
  11202. }
  11203.  
  11204. /* initializes the arguments and starts argument parsing */
  11205. static void GetArgs(int argc, char **argv)
  11206. {
  11207.   int res = 1;
  11208.   int i = 1, j;
  11209.  
  11210.   while(i < argc && res)
  11211.   {
  11212.     if((j = ParseArgEntry(argc-i, argv+i)) < 1)
  11213.       res = 0;
  11214.     else
  11215.       i += j;
  11216.   }
  11217.   if(!res || !args.infile)
  11218.     printhelp();
  11219. }
  11220.  
  11221. #endif
  11222.  
  11223. static strptr mygetfile(strptr name, size_t *len)
  11224. {
  11225.   strptr ptr = 0;
  11226.   FILE *infile;
  11227.  
  11228.   if((infile = fopen(name, "rb")))
  11229.   {
  11230.     if(!fseek(infile, 0, SEEK_END))
  11231.     {
  11232.       *len = ftell(infile);
  11233.       if(!fseek(infile, SEEK_SET, 0))
  11234.       {
  11235.         if((ptr = AllocListMem(*len+1)))
  11236.         {
  11237.           ptr[*len] = 0;
  11238. #ifdef DEBUG_OLD
  11239.   printf("mygetfile: '%s' size %ld\n", name, *len);
  11240. #endif
  11241.           if(fread(ptr, *len, 1, infile) != 1)
  11242.             ptr = 0;
  11243.         }
  11244.       }
  11245.     }
  11246.     fclose(infile);
  11247.   }
  11248.   return ptr;
  11249. }
  11250.  
  11251. int main(int argc, char **argv)
  11252. {
  11253.   uint32 mode = 0, pragmode = PRAGMODE_PRAGLIB, callmode = TAGMODE_BOTH;
  11254.   strptr amicall = 0, libcall = 0, amitags = 0, libtags = 0;
  11255.   strptr clibbuf;
  11256.   size_t clibsize = 0;
  11257.  
  11258.   GetArgs(argc, argv);
  11259.  
  11260.   if((tempbuf = (uint8 *) AllocListMem(TEMPSIZE)))
  11261.   {
  11262.     if(!(in.pos = in.buf = mygetfile(args.infile, &in.size)))
  11263.     {
  11264.       if(args.special == 200)
  11265.       {
  11266.         DoError(ERR_OPEN_FILE, 0, args.infile);
  11267.         exit(20);
  11268.       }
  11269.       else
  11270.       {
  11271.         sprintf((strptr)tempbuf, "%s" SFDFILEEXTENSION, args.infile);
  11272.         if(!(in.pos = in.buf = mygetfile((strptr)tempbuf, &in.size)))
  11273.         {
  11274.           sprintf((strptr)tempbuf, "%s" FDFILEEXTENSION, args.infile);
  11275.           if(!(in.pos = in.buf = mygetfile((strptr)tempbuf, &in.size)))
  11276.           {
  11277.             DoError(ERR_OPEN_FILE, 0, args.infile);
  11278.             exit(20);
  11279.           }
  11280.           else
  11281.             args.infile = DupString((strptr) tempbuf, strlen((strptr) tempbuf));
  11282.         }
  11283.         else
  11284.           args.infile = DupString((strptr) tempbuf, strlen((strptr) tempbuf));
  11285.       }
  11286.     }
  11287.     printf("SourceFile: %s\n", args.infile);
  11288.  
  11289.     MakeLines(in.pos, in.size);
  11290.  
  11291.     if((Flags & FLAG_DOCOMMENT) && (Flags & FLAG_SORTED)) /* is not possible to use both */
  11292.     {
  11293.       DoError(ERR_SORTED_COMMENT, 0);
  11294.       Flags &= (~FLAG_SORTED);
  11295.     }
  11296.  
  11297.     if(args.special == 200)
  11298.     {
  11299.       CreateFDFile();
  11300.       exit(0);
  11301.     }
  11302.  
  11303.     if(!GetTypes())
  11304.       exit(20);
  11305.  
  11306.     if(!ScanFDFile())
  11307.       exit(20);
  11308.  
  11309.     if(args.clib)
  11310.     {
  11311.       if(Flags2 & FLAG2_SFDMODE)
  11312.         DoError(ERR_SFD_AND_CLIB, 0);
  11313.       else
  11314.       {
  11315.         sprintf((strptr)tempbuf, "%s_protos.h", args.clib);
  11316.         if(!(clibbuf = mygetfile(args.clib, &clibsize)) && !(clibbuf = mygetfile((strptr)tempbuf, &clibsize)))
  11317.         {
  11318.           DoError(ERR_OPEN_FILE, 0, args.clib);
  11319.           exit(20);
  11320.         }
  11321.         ScanClibFile(clibbuf, clibbuf+clibsize);
  11322.       }
  11323.     }
  11324.  
  11325.     if(!MakeShortBaseName())
  11326.     {
  11327.       DoError(ERR_MISSING_SHORTBASENAME, 0);
  11328.       exit(20);
  11329.     }
  11330.  
  11331.     /* WARN when requesting obsolete types! */
  11332.     switch(args.special)
  11333.     {
  11334.     case 1: case 2: case 3: case 4: case 5: case 7:
  11335.       printf("You use obsolete data type %d, better use type 6!\n", args.special);
  11336.       break;
  11337.     case 11: case 15: case 71: case 72: case 75:
  11338.       printf("You use obsolete assembler text type %d, better use 90 to 99 or "
  11339.       "link libraries!\n", args.special);
  11340.       break;
  11341.     case 30: case 31: case 32: case 33: case 34: case 36: case 37: case 39:
  11342.       printf("You use obsolete proto type %d, better us type 38 or 35!\n", args.special);
  11343.       break;
  11344.     case 79:
  11345.       printf("Obsolete inline file 79 used, better take type 70 instead!\n");
  11346.       break;
  11347.     }
  11348.  
  11349.     if(args.special < 10) /* the pragma area is up to 9 */
  11350.     {
  11351.       mode = MODUS_PRAGMA;
  11352.       sprintf(filename, "%s_lib.h", ShortBaseName);
  11353.  
  11354.       switch(args.special)
  11355.       {
  11356.         case 0: break;
  11357.         case 1: pragmode = PRAGMODE_PRAGSLIB; amicall = ""; break;
  11358.         case 2: sprintf(filename, "%s_pragmas.h", ShortBaseName);
  11359.                 pragmode = PRAGMODE_PRAGSPRAGS; libcall = ""; break;
  11360.         case 3: sprintf(filename, "%s_pragmas.h", ShortBaseName);
  11361.                 pragmode = PRAGMODE_PRAGSPRAGS; libcall = "";
  11362.                 libtags = "def " TEXT_SAS_60; break;
  11363.         case 4: amicall = ""; break;
  11364.         case 5: amicall = amitags = ""; break;
  11365.         case 7: Flags |= FLAG_GNUPRAG; /* no break ! */
  11366.         case 6: amicall = " defined(" TEXT_AZTEC ") || defined("
  11367.                 TEXT_MAXON ") || defined(" TEXT_STORM ")";
  11368.                 libcall = " defined(" TEXT_DICE ") || defined(" TEXT_SAS ")";
  11369.                 libtags = "def " TEXT_SAS_60; amitags ="def " TEXT_STORM; break;
  11370.         default: mode = MODUS_ERROR; break;
  11371.       }
  11372.  
  11373.       if(args.mode > 0 && args.mode < 5)
  11374.         pragmode = args.mode;
  11375.     }
  11376.     else if(args.special < 20) /* the misc area is up to 19 */
  11377.     {
  11378.       if(args.mode > 0 && args.mode < 4)
  11379.         callmode = args.mode - 1;
  11380.       switch(args.special)
  11381.       {
  11382.       case 10: mode = MODUS_CSTUB;
  11383.         sprintf(filename, "%s_cstub.h", ShortBaseName); break;
  11384.       case 11: mode = MODUS_STUBTEXT;
  11385.         sprintf(filename, "%s_stub.s", ShortBaseName); break;
  11386.       case 12: mode = MODUS_STUBCODE;
  11387.         sprintf(filename, "%s.lib", ShortBaseName); break;
  11388.       case 13: Flags |= FLAG_LOCALREG; /* no break ! */
  11389.       case 14: mode = MODUS_LOCALDATA;
  11390.         sprintf(filename, "%s_loc.h", ShortBaseName); break;
  11391.       case 15: mode = MODUS_STUBTEXT; callmode = TAGMODE_NORMAL;
  11392.         Flags ^= FLAG_PASCAL;
  11393.         sprintf(filename, "%s_stub.s", ShortBaseName); break;
  11394.       case 16: mode = MODUS_STUBCODE; callmode = TAGMODE_NORMAL;
  11395.         Flags ^= FLAG_PASCAL;
  11396.         sprintf(filename, "%s.lib", ShortBaseName); break;
  11397.       case 17: mode = MODUS_BMAP; callmode = TAGMODE_NORMAL;
  11398.         sprintf(filename, "%s.bmap", ShortBaseName); break;
  11399.       case 18: mode = MODUS_EMODULE;
  11400.         sprintf(filename, "%s.m", ShortBaseName); break;
  11401.       default: mode = MODUS_ERROR; break;
  11402.       }
  11403.     }
  11404.     else if(args.special < 30) /* the lvo area is up to 29 */
  11405.     {
  11406.       switch(args.special)
  11407.       {
  11408.       case 20: case 22: mode = MODUS_LVO+args.special-20;
  11409.         sprintf(filename, "%s_lvo.i", ShortBaseName); break;
  11410.       case 21: case 23: mode = MODUS_LVO+args.special-20;
  11411.         sprintf(filename, "%s_lib.i", ShortBaseName); break;
  11412.       case 24: mode = MODUS_LVOLIB;
  11413.         sprintf(filename, "%slvo.o", ShortBaseName); break;
  11414.       default: mode = MODUS_ERROR; break;
  11415.       }
  11416.     }
  11417.     else if(args.special < 40) /* the proto area is up to 39 */
  11418.     {
  11419.       if(args.special < 40)
  11420.       {
  11421.         mode = MODUS_PROTO+args.special-30;
  11422.         sprintf(filename, "%s.h", ShortBaseName);
  11423.       }
  11424.       else
  11425.         mode = MODUS_ERROR;
  11426.     }
  11427.     else if(args.special < 50) /* the inline area is up to 49 */
  11428.     {
  11429.       if(args.mode > 0 && args.mode < 4)
  11430.         callmode = args.mode - 1;
  11431.  
  11432.       switch(args.special)
  11433.       {
  11434.       case 40: case 41: case 42: case 43: case 44: case 45: case 46:
  11435.       case 47:
  11436.         mode = MODUS_INLINE+args.special-40;
  11437.         sprintf(filename, "%s.h", ShortBaseName); break;
  11438.       default: mode = MODUS_ERROR; break;
  11439.       }
  11440.     }
  11441.     else if(args.special < 60) /* the PowerUP area is up to 59 */
  11442.     {
  11443.       if(args.mode > 0 && args.mode < 4)
  11444.         callmode = args.mode - 1;
  11445.  
  11446.       switch(args.special)
  11447.       {
  11448.       case 50: case 51: case 52: mode = MODUS_INLINE+args.special-50;
  11449.         sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_POWERUP;
  11450.         break;
  11451.       case 53:
  11452.         sprintf(filename, "%s_pragmas.h", ShortBaseName);
  11453.         mode = MODUS_SASPOWER; break;
  11454.       case 54:
  11455.         sprintf(filename, "%s.h", ShortBaseName);
  11456.         mode = MODUS_PROTOPOWER; break;
  11457.       default: mode = MODUS_ERROR; break;
  11458.       }
  11459.     }
  11460.     else if(args.special < 70) /* the PASCAL stuff */
  11461.     {
  11462.       if(args.special == 60)
  11463.       {
  11464.         mode = MODUS_PASCAL;
  11465.         sprintf(filename, "%s.pas", ShortBaseName);
  11466.       }
  11467.       else
  11468.         mode = MODUS_ERROR;
  11469.     }
  11470.     else if(args.special < 80) /* the VBCC stuff */
  11471.     {
  11472.       if(args.mode > 0 && args.mode < 4)
  11473.         callmode = args.mode - 1;
  11474.  
  11475.       switch(args.special)
  11476.       {
  11477.       case 70: mode = MODUS_VBCCINLINE;
  11478.         sprintf(filename, "%s_protos.h", ShortBaseName); break;
  11479.       case 71: case 72: case 75:
  11480.         mode = MODUS_VBCC+args.special-71;
  11481.         sprintf(filename, "%s_stub.s", ShortBaseName); break;
  11482.       case 73: case 74:
  11483.         mode = MODUS_VBCC+args.special-71;
  11484.         sprintf(filename, "%s.lib", ShortBaseName); break;
  11485.       case 76:
  11486.         mode = MODUS_VBCCPUPLIB;
  11487.         sprintf(filename, "lib%s.a", ShortBaseName); break;
  11488.       case 77: mode = MODUS_VBCCWOSINLINE;
  11489.         sprintf(filename, "%s_protos.h", ShortBaseName); break;
  11490.       case 78: mode = MODUS_VBCCMORPHCODE;
  11491.         sprintf(filename, "lib%s.a", ShortBaseName); break;
  11492.       case 79: mode = MODUS_VBCCINLINE;
  11493.         Flags2 |= FLAG2_OLDVBCC;
  11494.         callmode = TAGMODE_NORMAL;
  11495.         sprintf(filename, "%s_protos.h", ShortBaseName); break;
  11496.       default: mode = MODUS_ERROR; break;
  11497.       }
  11498.     }
  11499.     else if(args.special < 90) /* redirect stuff */
  11500.     {
  11501.       mode = MODUS_REDIRECT;
  11502.       switch(args.special)
  11503.       {
  11504.       case 80: sprintf(filename, "%s_pragmas.h", ShortBaseName); break;
  11505.       case 81: sprintf(filename, "%s_lib.h", ShortBaseName); break;
  11506.       case 82: sprintf(filename, "%s.h", ShortBaseName); break;
  11507.       case 83: sprintf(filename, "%s_protos.h", ShortBaseName); break;
  11508.       default: mode = MODUS_ERROR; break;
  11509.       }
  11510.     }
  11511.     else if(args.special < 100) /* multifile stuff */
  11512.     {
  11513.       Flags |= FLAG_SINGLEFILE;
  11514.       switch(args.special)
  11515.       {
  11516.       case 90:
  11517.         if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
  11518.         mode = MODUS_ASMTEXTSF; filenamefmt = "%s.s";
  11519.         break;
  11520.       case 91:
  11521.         if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
  11522.         mode = MODUS_VBCCPUPTEXTSF; filenamefmt = "%s.s";
  11523.         break;
  11524.       case 92:
  11525.         if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
  11526.         mode = MODUS_VBCCWOSTEXTSF; filenamefmt = "%s.s";
  11527.         break;
  11528.       case 93:
  11529.         if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
  11530.         mode = MODUS_VBCCMORPHTEXTSF; filenamefmt = "%s.s";
  11531.         break;
  11532.       default: mode = MODUS_ERROR; break;
  11533.       }
  11534.     }
  11535.     else if(args.special < 110) /* PPC lvo's */
  11536.     {
  11537.       switch(args.special)
  11538.       {
  11539.       case 100: case 101: mode = MODUS_LVOPPC+args.special-100;
  11540.         sprintf(filename, "%s_lib.i", ShortBaseName);
  11541.         break;
  11542.       case 104: case 105: mode = MODUS_LVOPPC+args.special-104;
  11543.         Flags |= FLAG_ABIV4;
  11544.         sprintf(filename, "%s_lib.i", ShortBaseName);
  11545.         break;
  11546.       case 103: mode = MODUS_LVOLIB;
  11547.         sprintf(filename, "%slvo.o", ShortBaseName);
  11548.         break;
  11549.       case 107: mode = MODUS_LVOLIB;
  11550.         Flags |= FLAG_ABIV4;
  11551.         sprintf(filename, "%slvo.o", ShortBaseName);
  11552.         break;
  11553.       case 102: mode = MODUS_LVOLIBPPC;
  11554.         sprintf(filename, "%slvo.o", ShortBaseName); break;
  11555.       case 106: mode = MODUS_LVOLIBPPC;
  11556.         Flags |= FLAG_ABIV4;
  11557.         sprintf(filename, "%slvo.o", ShortBaseName); break;
  11558.       default: mode = MODUS_ERROR; break;
  11559.       }
  11560.     }
  11561.     else if(args.special < 120) /* different files */
  11562.     {
  11563.       if(args.mode > 0 && args.mode < 4)
  11564.         callmode = args.mode - 1;
  11565.  
  11566.       switch(args.special)
  11567.       {
  11568.       case 110: mode = MODUS_FD;
  11569.         sprintf(filename, "%s_lib.fd", ShortBaseName);
  11570.         if(Flags & FLAG_SORTED) /* is not possible to use here */
  11571.         {
  11572.           DoError(ERR_SORTED_SFD_FD, 0);
  11573.           Flags &= (~FLAG_SORTED);
  11574.         }
  11575.         break;
  11576.       case 111: mode = MODUS_CLIB; Flags2 |= FLAG2_CLIBOUT;
  11577.         sprintf(filename, "%s_protos.h", ShortBaseName);
  11578.         break;
  11579.       case 112: mode = MODUS_SFD; Flags2 |= FLAG2_SFDOUT;
  11580.         sprintf(filename, "%s_lib.sfd", ShortBaseName);
  11581.         if(callmode == 1)
  11582.         {
  11583.           callmode = 2;
  11584.           DoError(ERR_ONLYTAGMODE_NOTALLOWED, 0);
  11585.         }
  11586.         
  11587.         if(Flags & FLAG_SORTED) /* is not possible to use here */
  11588.         {
  11589.           DoError(ERR_SORTED_SFD_FD, 0);
  11590.           Flags &= (~FLAG_SORTED);
  11591.         }
  11592.         break;
  11593.       default: mode = MODUS_ERROR; break;
  11594.       }
  11595.     }
  11596.     else if(args.special < 130) /* auto libopen files */
  11597.     {
  11598.       if(args.mode > 0 && args.mode < 4) /* for 122 */
  11599.         callmode = args.mode - 1;
  11600.  
  11601.       switch(args.special)
  11602.       {
  11603.       case 120: mode = MODUS_GENAUTO;
  11604.         sprintf(filename, "%s_autoopenlib.c", ShortBaseName);
  11605.         break;
  11606.       case 121: mode = MODUS_GENAUTO+(args.special-120);
  11607.         sprintf(filename, "%s_autoopenlib.lib", ShortBaseName);
  11608.         break;
  11609.       case 122: mode = MODUS_VBCCMORPHINLINE;
  11610.         PPCRegPrefix = ""; /* no "r" allowed */
  11611.         sprintf(filename, "%s_protos.h", ShortBaseName);
  11612.         break;
  11613.       default: mode = MODUS_ERROR; break;
  11614.       }
  11615.     }
  11616.     else if(args.special < 140) /* the MorphOS area is up to 139 */
  11617.     {
  11618.       if(args.mode > 0 && args.mode < 4)
  11619.         callmode = args.mode - 1;
  11620.  
  11621.       switch(args.special)
  11622.       {
  11623.       case 130: case 131: case 132: mode = MODUS_INLINE+args.special-130;
  11624.         sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_MORPHOS;
  11625.         break;
  11626.       case 133: mode = MODUS_INLINE+2;
  11627.         sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_MORPHOS;
  11628.         Flags2 |= FLAG2_DIRECTVARARGS;
  11629.         break;
  11630.       case 134: mode = MODUS_GATESTUBS;
  11631.         sprintf(filename, "%s_gates.h", ShortBaseName);
  11632.         break;
  11633.       case 135: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_PRELIB;
  11634.         sprintf(filename, "%s_gates.h", ShortBaseName);
  11635.         break;
  11636.       case 136: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_POSTLIB;
  11637.         sprintf(filename, "%s_gates.h", ShortBaseName);
  11638.         break;
  11639.       case 137: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_PRELIB|FLAG2_REGLIB;
  11640.         sprintf(filename, "%s_gates.h", ShortBaseName);
  11641.         break;
  11642.       case 138: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_POSTLIB|FLAG2_REGLIB;
  11643.         sprintf(filename, "%s_gates.h", ShortBaseName);
  11644.         break;
  11645.       default: mode = MODUS_ERROR; break;
  11646.       }
  11647.     }
  11648.  
  11649.     if(Flags & FLAG_SORTED)
  11650.       SortFDList();
  11651.  
  11652.     if((Flags & FLAG_DOCOMMENT) && (Flags & FLAG_SINGLEFILE)) /* is not possible to use both */
  11653.     {
  11654.       DoError(ERR_COMMENT_SINGLEFILE, 0);
  11655.       Flags &= (~FLAG_DOCOMMENT);
  11656.     }
  11657.  
  11658.     if(!mode || mode == MODUS_ERROR)
  11659.       printhelp();
  11660.  
  11661.     /* These modes need BaseName always. */
  11662.     if(!BaseName && (mode == MODUS_PRAGMA || mode == MODUS_STUBTEXT ||
  11663.     mode == MODUS_STUBCODE || mode == MODUS_EMODULE || (mode >= MODUS_GENAUTO &&
  11664.     mode <= MODUS_GENAUTO+9)))
  11665.     {
  11666.       DoError(ERR_MISSING_BASENAME, 0);
  11667.       exit(20);
  11668.     }
  11669.  
  11670.     if(args.header && args.header[0] && (args.header[0] != '@' || args.header[1]))
  11671.     {
  11672.       HEADER = mygetfile(args.header, &headersize);
  11673.       args.header = 0;
  11674.     }
  11675.  
  11676.     if(!(Flags & FLAG_SINGLEFILE))
  11677.     {
  11678.       if(!OpenDest(filename))
  11679.         exit(20);
  11680.     }
  11681.  
  11682.     /* from here mode is used as return result */
  11683.     if(mode >= MODUS_GENAUTO)
  11684.       mode = CreateGenAuto(filename, mode-MODUS_GENAUTO);
  11685.     else if(mode >= MODUS_LVOPPC)
  11686.       mode = CreateLVOFilePPC(mode-MODUS_LVOPPC);
  11687.     else if(mode >= MODUS_VBCC)
  11688.       mode = CreateVBCC(mode-MODUS_VBCC, callmode);
  11689.     else if(mode >= MODUS_INLINE)
  11690.       mode = CreateInline(mode-MODUS_INLINE, callmode);
  11691.     else if(mode >= MODUS_PROTO)
  11692.       mode = CreateProtoFile(mode-MODUS_PROTO+1);
  11693.     else if(mode >= MODUS_LVO)
  11694.       mode = CreateLVOFile(mode-MODUS_LVO+1);
  11695.     else if(mode == MODUS_VBCCMORPHINLINE)
  11696.       mode = CreateVBCCInline(2, callmode);
  11697.     else if(mode == MODUS_GATESTUBS)
  11698.       mode = CreateGateStubs(callmode);
  11699.     else if(mode == MODUS_SFD)
  11700.       mode = CreateSFD(callmode);
  11701.     else if(mode == MODUS_CLIB)
  11702.       mode = CreateClib(callmode);
  11703.     else if(mode == MODUS_FD)
  11704.       mode = CreateFD();
  11705.     else if(mode == MODUS_LVOLIBPPC)
  11706.       mode = CreateLVOLibPPC();
  11707.     else if(mode == MODUS_VBCCMORPHCODE)
  11708.       mode = CreateVBCCMorphCode(callmode);
  11709.     else if(mode == MODUS_VBCCMORPHTEXTSF) /* single files */
  11710.       mode = CallFunc(callmode, "\n%s", FuncVBCCMorphText);
  11711.     else if(mode == MODUS_VBCCWOSINLINE)
  11712.       mode = CreateVBCCInline(1, callmode);
  11713.     else if(mode == MODUS_VBCCWOSTEXTSF) /* single files */
  11714.       mode = CallFunc(callmode, "\n%s", FuncVBCCWOSText);
  11715.     else if(mode == MODUS_VBCCPUPTEXTSF) /* single files */
  11716.       mode = CallFunc(callmode, "\n%s", FuncVBCCPUPText);
  11717.     else if(mode == MODUS_ASMTEXTSF) /* single files */
  11718.       mode = CallFunc(callmode, "\n%s", FuncAsmText);
  11719.     else if(mode == MODUS_REDIRECT)
  11720.       mode = CreateProtoRedirect();
  11721.     else if(mode == MODUS_EMODULE)
  11722.       mode = CreateEModule(Flags & FLAG_SORTED);
  11723.     else if(mode == MODUS_LVOLIB)
  11724.       mode = CreateLVOLib();
  11725.     else if(mode == MODUS_VBCCPUPLIB)
  11726.       mode = CreateVBCCPUPLib(callmode);
  11727.     else if(mode == MODUS_VBCCINLINE)
  11728.       mode = CreateVBCCInline(0, callmode);
  11729.     else if(mode == MODUS_PASCAL)
  11730.       mode = CreateFPCUnit();
  11731.     else if(mode == MODUS_BMAP)
  11732.       mode = CreateBMAP();
  11733.     else if(mode == MODUS_PROTOPOWER)
  11734.       mode = CreateProtoPowerUP();
  11735.     else if(mode == MODUS_SASPOWER)
  11736.       mode = CreateSASPowerUP(callmode);
  11737.     else if(mode == MODUS_CSTUB)
  11738.       mode = CreateCSTUBSFile();
  11739.     else if(mode == MODUS_PRAGMA)
  11740.       mode = CreatePragmaFile(amicall, libcall, amitags, libtags, pragmode);
  11741.     else if(mode == MODUS_LOCALDATA)
  11742.       mode = CreateLocalData(filename, callmode);
  11743.     else if(mode)             /* MODUS_STUBTEXT starts with 1 */
  11744.       mode = CreateAsmStubs(mode, callmode);
  11745.  
  11746.     CloseDest(filename);
  11747.  
  11748.     if(!mode)
  11749.     {
  11750.       DoError(Output_Error ? ERR_UNKNOWN_ERROR : ERR_WRITING_FILE, 0);
  11751.       exit(20);
  11752.     }
  11753.     free(tempbuf);
  11754.   }
  11755.  
  11756.   return 0;
  11757. }
  11758.  
  11759.